We have created a custom exception at the ADF-BC level by overriding the JboException
class. In order to use application-specific error codes, we have introduced two new constructors. Both of them accept the error code as a parameter. One of them also accepts the message error parameters.
In our constructor, we call the base class' constructor and pass the message error code and parameters to it.
Then we override the getMessage()
method in order to construct the exception message. In getMessage()
, we first get access to the error messages resource bundle by calling ResourceBundle.getBundle()
as shown in the following code snippet:
This method accepts the name of the resource bundle and the locale. For the name of the resource bundle, we pass the constant ERRORS_BUNDLE
, which we define as com.packt.jdeveloper.cookbook.shared.bc.exceptions.messages.ErrorMessages
. This is the ErrorMessages.properties
file in the com/packt/jdeveloper/cookbook/shared/bc/exceptions/messages
directory where we have added all of our messages. For the locale, we use the default locale by calling Locale.getDefault()
.
Then we proceed by loading the error message from the bundle:
An error message definition in the messages resource bundle looks similar to the following:
As you can see, we have added the string prefix message
. to the actual error message code. How you form the error message identifiers in the resource bundle is up to you. You could, for example, use a module identifier for each message and change the code in getMessage()
appropriately. Also, we have used braces, that is, {1}, {2}
as placeholders for the actual message parameter values. Based on all these, we constructed the message identifier by adding the message prefix to the message error code as: MESSAGE_PREFIX + this.getErrorCode()
and called getString()
on the messagesBundle
to load it.
Then we proceed with iterating the message parameters. In a similar fashion, we call getString()
on the parameters bundle to load the parameter values.
The parameter definitions in the parameters resource bundle look similar to the following:
So we add the prefix parameter
to the actual parameter identifier before loading it from the bundle.
The last step is to replace the parameter placeholders in the error message with the actual parameter values. We do this by calling replaceAll()
on the raw error message, as shown in the following code snippet:
For testing purposes, we have added a main()
method to test our custom exception. You will similarly throw
the exception in your business components code, as follows:
You can combine the error message and the error message parameters bundles into a single resource bundle, if you want, and change the getMessage()
method as needed to load both from the same resource bundle.
By default, exceptions are bundled at the transaction level for ADF-BC-based web applications. This means that all exceptions thrown during attribute and entity validations are saved and reported once the validation process is complete. In other words, the validation will not stop on the first error, rather it will continue until the validation process completes and then report all exceptions in a single error message. Bundled validation exceptions are implemented by wrapping exceptions as details of a new parent exception that contains them. For instance, if multiple attributes in a single entity object fail attribute validation, these multiple ValidationException
objects are wrapped in a RowValException
. This wrapping exception contains the row key of the row that has failed validation. At transaction commit time, if multiple rows do not successfully pass the validation performed during commit, then all of the RowValException
objects will get wrapped in an enclosing TxnValException
object. Then you can use the getDetails()
method of the JboException
base exception class to recursively process the bundled exceptions contained inside it.
Exception bundling can be configured at the transaction level by calling setBundledExceptionMode()
on the oracle.jbo.Transaction
. This method accepts a Boolean value indicating that bundled transactions will be used or not, respectively.
Note
Note that in the Using a generic backing bean actions framework recipe in this chapter, we refactored the code in getMessage()
to a reusable BundleUtils.loadMessage()
method. Consequently, we changed the ExtJboException getMessage()
in that recipe to the following: