# Exception Clause

You can use the _Exception Clause_ in the Java [DSL](dsl.md) to specify the error handling you require on a per exception type basis using the **`onException()`** method. To get started we give quick sample before digging into how it works.

For example if you want to perform a specific piece of processing if a certain exception is raised you can do this simply via:

-   Java
    
-   XML
    
-   YAML
    

```java
onException(ValidationException.class)
    .to("activemq:validationFailed");

from("seda:inputA")
    .to("validation:foo/bar.xsd", "activemq:someQueue");

from("seda:inputB")
    .to("direct:foo")
    .to("rnc:mySchema.rnc", "activemq:anotherQueue");
```

```xml
<onException>
    <exception>org.apache.camel.ValidationException</exception>
    <to uri="activemq:validationFailed"/>
</onException>

<route>
    <from uri="seda:inputA"/>
    <to uri="validation:foo/bar.xsd"/>
    <to uri="activemq:someQueue"/>
</route>

<route>
    <from uri="seda:inputB"/>
    <to uri="direct:foo"/>
    <to uri="rnc:mySchema.rnc"/>
    <to uri="activemq:anotherQueue"/>
</route>
```

```yaml
- onException:
    exception:
      - org.apache.camel.ValidationException
    steps:
      - to:
          uri: activemq:validationFailed
- route:
    from:
      uri: seda:inputA
      steps:
        - to:
            uri: validation:foo/bar.xsd
        - to:
            uri: activemq:someQueue
- route:
    from:
      uri: seda:inputB
      steps:
        - to:
            uri: direct:foo
        - to:
            uri: rnc:mySchema.rnc
        - to:
            uri: activemq:anotherQueue
```

Here if the processing of **`seda:inputA`** or **`seda:inputB`** cause a **`ValidationException`** to be thrown (such as due to the XSD validation of the [Validation](../components/4.18.x/validator-component.md) component), then the message will be sent to the **`activemq:validationFailed`** queue.

You can define multiple **`onException`** clauses for different behavior:

-   Java
    
-   XML
    
-   YAML
    

```java
onException(ValidationException.class)
    .to("activemq:validationFailed");

onException(com.foo.ShipOrderException.class)
    .to("activemq:shipFailed");

from("seda:order")
    .to("bean:processOrder");
```

```xml
<onException>
    <exception>org.apache.camel.ValidationException</exception>
    <to uri="activemq:validationFailed"/>
</onException>
<onException>
    <exception>com.foo.ShipOrderException</exception>
    <to uri="activemq:shipFailed"/>
</onException>

<route>
    <from uri="seda:order"/>
    <to uri="bean:processOrder"/>
</route>
```

```yaml
- onException:
    exception:
      - org.apache.camel.ValidationException
    steps:
      - to:
          uri: activemq:validationFailed
- onException:
    exception:
      - com.foo.ShipOrderException
    steps:
      - to:
          uri: activemq:shipFailed
- route:
    from:
      uri: seda:order
      steps:
        - to:
            uri: bean:processOrder
```

## Scopes

Exception clauses is scoped as either:

-   global (for Java DSL that is per **`RouteBuilder`** instances, to reuse, see note below)
    
-   or route specific
    

Where the **global** are the simplest and most easy to understand. In the advanced section we dig into the route specific and even combining them. However

Global scope for Java DSL is per **`RouteBuilder`** instance, so if you want to share among multiple **`RouteBuilder`** classes, then create a base abstract **`RouteBuilder`** class and put the error handling logic in its **`configure`** method. And then extend this class, and make sure to class **`super.configure()`**. We are just using the Java inheritance technique.

## How Does Camel Select Which Clause Should Handle a Given Thrown Exception?

Camel uses **`DefaultExceptionPolicyStrategy`** to determine a strategy how an exception being thrown should be handled by which **`onException`** clause. The strategy is:

-   the order in which the **`onException`** is configured takes precedence. Camel will test from first…​last defined.
    
-   Camel will start from the bottom (nested caused by) and recursive up in the exception hierarchy to find the first matching **`onException`** clause.
    
-   **`instanceof`** test is used for testing the given exception with the **`onException`** clause defined exception list. An exact **`instanceof`** match will always be used, otherwise the **`onException`** clause that has an exception that is the closets super of the thrown exception is selected (recurring up the exception hierarchy).
    

This is best illustrated with an exception:

_Java-only: exception policy selection order_

```java
onException(IOException.class)
    .maximumRedeliveries(3);

onException(OrderFailedException.class)
    .maximumRedeliveries(2);
```

In the sample above we have defined two exceptions in which **`IOException`** is first, so Camel will pickup this exception if there is a match. **`IOException`** that is more general is selected then.

So if an exception is thrown with this hierarchy:

\+ RuntimeCamelException (wrapper exception by Camel)
    + OrderFailedException
        + IOException
            + FileNotFoundException

Then Camel will try testing the exception in this order: **`FileNotFoundException`**, **`IOException`**, **`OrderFailedException`** and **`RuntimeCamelException`**. As we have defined a **`onException(IOException.class)`** Camel will select this as it’s the **closest** match.

If we add a third **`onException`** clause with the **`FileNotFoundException`**

_Java-only: adding a more specific exception clause_

```java
onException(IOException.class)
    .maximumRedeliveries(3);

onException(OrderFailedException.class)
    .maximumRedeliveries(2);

onException(FileNotFoundException.class)
    .handled(true)
    .to("log:nofile");
```

Then with the previous example Camel will now use the last **`onException(FileNotFoundException.class)`** as its an **exact** match. Since this is an exact match it will override the general **`IOException`** that was used before to handle the same exception thrown.

Now a new situation if this exception was thrown instead:

\+ RuntimeCamelException (wrapper exception by Camel)
    + OrderFailedException
        + OrderNotFoundException

Then the **`onException(OrderFailedException.class)`** will be selected - no surprise here.

And this last sample demonstrates the **`instanceof`** test aspect in which Camel will select an exception if it’s an instance of the defined exception in the **`onException`** clause. Illustrated as:

\+ RuntimeCamelException (wrapper exception by Camel)
    + SocketException

Since **`SocketException`** is an **`instanceof IOException`**, Camel will select the **`onException(IOException.class)`** clause.

## More Information

For detailed documentation on specific topics, see the following sub-pages:

-   [Redelivery](exception-redelivery.md) — Configuring redelivery policy, async delayed redelivery, catching multiple exceptions
    
-   [Handling Patterns](exception-handling-patterns.md) — Handled vs continued, using original message, custom failure handlers
    
-   [Advanced Usage](exception-advanced.md) — Global vs route-specific, onWhen predicate, onRedelivery processor, custom strategies