Reading Time: 6 minutes

We put a lot of effort in Mule 3.3 to improve error handling in Mule ESB. One of the most common requirements during error handling was the ability to continue processing the same message that was being processed at the time of the exception. And that’s why that is the default behavior for the new exception strategies shipped with Mule 3.3.

Another very common use case was the need to differentiate between handled and unhandled exceptions within a flow. In this case we are going to focus on handled exception and the new catch exception strategy.

latest report
Learn why we are the Leaders in API management and iPaaS

Catch exception strategy allows you to gracefully manage errors during a flow execution. It’s like using a catch in java without rethrowing the exception. We are going to see two examples were you can use catch exception strategy:

  • Handle exception and return a custom message
  • Consume message and move it to a dead letter queue

Handle exception and return a custom message

Use case: We have to build a order REST service in Mule. In case of an exception we need to return a JSON response with an status of failure and a message with information about the problem.

Rest order service –  Mule Studio flow

    <flow name="RestService" doc:name="RestService">
        <http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8090" path="orders" doc:name="Orders service endpoint"></http:inbound-endpoint>
        <component class="OrderService" doc:name="Order Service"></component>
        <catch-exception-strategy doc:name="Catch Exception Strategy">
            <expression-component doc:name="Create error response">#[payload = "{\"status\":\"error\", \"message\":\"" + exception.cause.message + "\"}"]</expression-component>
        </catch-exception-strategy>
    </flow>

Rest order service – Mule configuration

In case of an error we are handling the exception with a catch exception strategy and returning a JSON message with the information of the exception.

 

Consume message and move it to a dead letter queue

Use case: A CRM system produces notifications that must be send by email to customers. Those notifications are placed in a JMS queue. We need to build another application that  process those notifications, generate an email with the information provided and finality sends it to the addressee. In case of an error during the email generation we have to move the processed notification to a notifications dead letter queue.

Notification service – Mule Studio flow

    <flow name="NotificationService" doc:name="simple-ha-appFlow1">
        <jms:inbound-endpoint queue="notifications" connector-ref="ActiveMQConnector" doc:name="Notifications Queue Consumer">
            <jms:transaction action="ALWAYS_BEGIN"/>
        </jms:inbound-endpoint>
        <smtp:outbound-endpoint host="emailserver" port="25" to="#[payload['to]]" from="notification.app@company.com" subject="#[payload['subject']]" responseTimeout="10000" doc:name="Send Notification By Email"/>
        <catch-exception-strategy doc:name="Catch Exception Strategy">
            <expression-component doc:name="Create Notification Failure Object">#[payload = new com.company.notification.NotificationFailure(payload, exception)]</expression-component>
            <jms:outbound-endpoint queue="notificationsFailures" connector-ref="ActiveMQConnector" doc:name="Notification Failures Queue">
                <jms:transaction action="ALWAYS_JOIN"/>
            </jms:outbound-endpoint>
        </catch-exception-strategy>
    </flow>

 Notification service – Mule configuration

In this case, if an exception is thrown within our flow, we are creating a new notification object with the information of notification plus the exception thrown. Notice that the transaction is still running and every message processor inside catch exception strategy is able to join it. At the end of the execution  the catch exception strategy will always commit the transaction.

Conclusion

Now you have a better semantics to handle exception in your flows and no longer need to create a custom exception strategy in order to change the result of a flow in case of an error.

Keep in mind that using a catch exception strategy means that the source message was successfully consumed. So for transactional transport it will always commit the transaction and for reliable transports it will not restore the original message. For more information about reliable transports see Implementing Reliable Acquisition Flow.

What’s Next?

If you want to know more about error handling improvements in Mule 3.3 take a look at the updated error handling documentation. You can also download Mule and create a new Mule Studio project using one of the examples shipped with the distribution.