Skip to main content
Version: 4.15.1

Using exceptions

When a message enters the Error Route as a failed exchange it contains an element with detailed information about why it failed; the exception. The data in the exception can be used for logging, monitoring, reporting and/or functionally handling failed exchanges.

Exceptions

Dovetail is built on Apache Camel. Below you'll find a schematic view of a Camel message and exchange. The message is the 'payload' sent between components of a flow, while an exchange is the message's 'container' during routing between components. When an exchange is unsuccesful, it is routed to the FailedExchange component in the Error Route.

Schematic view of a Camel message and exchange

As shown in the image above, the exception is an essential element of an exchange. It contains detailed information about any exceptions and/or errors that occur during a failed exchange between components.

Below you'll find two examples of the JSON data in the exception element. Notice the additional available JSON keys for an HTTP exception compared to a 'normal' exception.

{
"cause": null,
"stackTrace": [ { "This array": "Contains the full stackTrace of the exception" } ],
"message": "The provided JSON could not be parsed to either a JSON object or a JSON array.",
"suppressed": [],
"localizedMessage": "The provided JSON could not be parsed to either a JSON object or a JSON array."
}

Exception expressions

The expressions to retrieve (parts of) the exception data from a failed exchange are shown in the table below.

Exception expressionDescription
${exception}The complete exception including the stackTrace
${exception.class}The class of the exception
${exception.message}The value of the message key of the exception
${exception.responseBody}The value of the responseBody key of an HTTP exception *
${exception.[jsonkey]}The value of any JSON key in the exception data *

* Only keys that are available in the exception data can be retrieved. When you try to retrieve a key that doesn't exist an error will be thrown. Read more about how to implement this below.

Retrieving exceptions from different datasets

Depending on the class of the exception, additional JSON keys with data are available. In practice this means that HTTP exceptions have an extended dataset with more detail. By evaluating the ${exception.class} value, for instance with a Filter component or a Content Router component, you can ensure that you only use expressions for keys that are available.

In the example below, the SetHeaders components in the top row gather all kinds of metrics about a failed exchange, including its class and message. The SQL component inserts this data into a database.

Using a Filter to differentiate between exception expressions

Then the Filter component on the bottom row checks if the class of the exception is an HTTP exception, using this expression:

${exception.class} == 'org.apache.camel.http.base.HttpOperationFailedException'

Only when this evaluation is true it reaches the SetHeaders component in the bottom row that contains expressions specific for HTTP exceptions, i.e. ${exception.responseBody}. And finally the SQL component updates the log line with this extra data.

content router instead of filter

Alternatively you use a Content Router component with a rule containing the same expression as shown above and segment the exception expresssions this way.

tip

Refer to Management by Exception guide for a full tutorial on how to log exceptions from multiple tenants and/or instances into one database.

Last update on Apr 8, 2024