
Introduction
Java exception handling enables your Java applications to handle errors sensibly. Exception handling is a very important yet often neglected aspect of writing robust Java applications or components. When an error occurs in a Java program it usually results in an exception being thrown. How you throw, catch and handle these exception matters. There are several different ways to do so. Not all are equally efficient and fail safe.
Exceptions are the recommended mechanism for handling errors in a Cúram application. Exceptions save the developer from having to check the status of each attempted operation. A single try..catch construct can enclose many statements, each of which can raise an exception.
In a Cúram application, exceptions can originate from various parts of generated code. Please find it below –
- Database Access Layer (DAL): It throws exceptions in the event of a database error, application developers can throw pre-defined exceptions or customized exceptions.
- Remote Interface Layer (RIL):
- Custom Code
There are two basic forms of exceptions used in Curam –
- Checked Exception: Checked Exception are the exceptions that are checked at compile time. If some code within a method throws a checked exception, then the method must either handle the exception or it must specify the exception using throws keyword.
- Unchecked Exception:Unchecked Exception are the exceptions that are not checked at compiled time.In Java exceptions under Error and RuntimeException classes are unchecked exceptions, everything else under throwable is checked.
Checked Exception
Checked exceptions are subclasses of curam.util.exception.AppException and curam.util.exception.InformationalException.
These exceptions must be explicitly caught or listed in the throws clause of the method.
In a Cúram application, checked exceptions can arrive at the Remote Interface Layer (RIL), despite being checked, a throws clause can unwind all the way to the RIL. Once here they are converted to a different form of exception which is thrown to the client, and may write information from the exception to the log file. To avoid this a developer can write code to catch exceptions and handle them and/or re-throw them before the exception reaches the RIL.
The following happens when the RIL catches a checked exception:
- The text for the exception is loaded from a message catalog file.
- If the exception is loggable, then the text will be formatted, with arguments inserted and written to the log file in the default server language.
- If the exception is loggable and includes a stack trace this will be written to the log file.
- An exception is created and thrown to the client. This contains the name of the message catalog, the ID of the message, and the exception arguments if any.
- The client receives the exception and uses the catalog name and message ID to look-up a localized version of the message. It then inserts and formats the arguments into a message and displays the message.
Example: Please find screenshot below which include throw exception using AppException in Curam.
Message File: Please find message file screenshot which used in above exception handling code. Some placeholder available in the messaged to add –
- s – string
- n – numeric
- d – date
- t – time
- z – date/time
- c – code table item
%1s means first argument as String.
%2s means second argument as String.
%3c means third argument as Codetable Code
curam.util.exception.AppException e = new AppExeption(EXAMPLE.ID_EXAMPLE_MESSAGE);
e.arg(Person.FirstName);
e.arg(Person.Surname);
throw e;
Unchecked Exception
Unchecked exceptions are subclasses of curam.util.exception.AppRuntimeException. These exceptions do not have to be explicitly handled as they inherit from the Java Exception and RuntimeException classes respectively. Typically, database problems (such as a RecordLockedException) are thrown as unchecked exceptions. This means that there is no need for code to tediously check for a RecordLockedException each time the database is accessed.
The RIL also catches unchecked exceptions to perform default actions.
- The text for the exception is loaded from a message catalog file.
- The text is formatted with arguments inserted and written to the log file in the default server language.
- A stack trace is written to the log file.
- A new exception is created and thrown to the client. This exception states that the original exception was Unhandled. The original exception is mapped because the descriptive text is at too low a level to make sense to a user.
Standard core infrastructure Exception
Core infrastructure is having its own pre defined exception which we can use to throw the exception, please find some important exception below –
- RecordNotFoundException: It can be thrown by singleton reads, updates and removes of the database.
- RecordDeletedException: It always thrown in precedence to a RecordNotFoundException.Also, it can be thrown when an optimistic update fails because the target record has been deleted . With optimistic locking enabled the record is re-read to obtain the version number. If the record is no longer present this exception is thrown.
- DuplicateRecordExceptio: It can be thrown by insert and update operations (entity insert, nsinsert, modify, nsmodify, nkmodify operations).
- OtherDatabaseException can be thrown by any of the entity operations if the database reports an error which does not map to one of the above exceptions.and RecordDeletedException can be thrown by update operations with optimistic locking.
- MultipleRecordException: It can be thrown by singleton reads of the database (entity read, nsread, nkread operations) if multiple records are found which meet the specified selection criteria.
- ReadmultiMaxException: It can be thrown by multiple reads of the database (entity readmulti, nsmulti, nkreadmulti operations) if more record are retrieved than the maximum specified in the application model.
- RecordLockedException: It can be thrown by any of the entity operations if a deadlock or lock timeout occurs.
- OtherDatabaseException: It can be thrown by any of the entity operations if the database reports an error which does not map to one of the above exceptions.
Record Not Found Indicator
Record Not Found Indicator used to restrict RecordNotFoundException. Each reads of the database (entity read, nsread, nkread operations) which could potentially throw a RecordNotFoundException has overloads added to take a Record Not Found Indicator variable.
The reasons for providing a Record Not Found Indicator are:
- To save the overhead of creating and throwing an exception whenever a record cannot be found, as this is an expensive process in some JVM s.
- To make it easier to write code which simply checks for the existence of a record.
curam.util.type.NotFoundIndicator class wrap a Boolean indicator which indicates whether the required record could not be found.
When this indicator is passed into one of the above read operations, the operation will never throw a RecordNotFoundException if the record does not exist but will instead set the boolean flag inside NotFoundIndicator to true, and return a value of null. If the record is found, the boolean flag inside NotFoundIndicator is set to false, and the record is returned.
Whenever a developer wishes to pass a NotFoundIndicator into a singleton read operation, it is always passed in as the first argument.
Read without NotFoundIndicator:
try {
bankAccountDtls = bankAccount.read(bankAccountKey);
} catch (RecordNotFoundException rnf) {
// record was not found...
}
Read with NotFoundIndicator:
final NotFoundIndicator notFoundInd =
new curam.util.type.NotFoundIndicator();
bankAccountDtls = bankAccount.read(notFoundInd, bankAccountKey);
if (notFoundInd.isNotFound()) {
// record was not found...
} else {
// record was found...
}
Now Developer can check before accessing value like -
if(notFoundInd.isNotFound()){
Long accountNumber = bankAccountDtls.accountNumber;
}
Note: When the client receives the exception and uses the catalog name and message ID to look-up a localized version of the message. It then inserts and formats the arguments into the message and displays the message.