Error handling in event driven systems like Mule can be a challenge to understand, if you have worked with Mule you’ll know that there are exception strategies and this post will help you get the most out of them.
How error handling works in Mule
Note: In this blog we are going to talk about flow since it’s the preferred configuration style but the same applies to services.
Mule errors are represented by exceptions, so when your transformer, endpoint or any other processor fails it throws an exception. When an exception is thrown, you need a way to manage it. In Mule, the key is <default-exception-strategy> element. Once an exception is thrown normal flow execution will stop and will continue processing on the exception strategy. Inside it you can put message processors to do whatever you want to handle the exception. Currently <default -exception-strategy> only allows one message processor, but you can overcome this issue by using a <processor-chain> element.
MuleEvent flow when a message processor throws an exception
Implicit exception strategy
You may be wondering what happens if an exception is raised and you don´t define a <default-exception-strategy> element. Well, you will get one for free. Every flow has an exception strategy configured by default. Default behavior is to log the exception, rollback the transaction if there’s one and close any open input stream.
When an exception is thrown you get exception and the payload before the exception. Inside the <default-exception-strategy> block the MuleMessage will be transformed to contain information about the exception. A new payload of type ExceptionMessage will be created. It will contain the current payload (in the payload attribute) and the exception (in the exception attribute) and then the message flows as usual.
Exchange pattern request-response and Exception Strategy
What if the flow exchange pattern is request-response? Do I still get a response? In that case after executing the <default-exception-strategy> block a different message will be returned back to the caller. This MuleMessage will have a NullPayload as payload and an ExceptionPayload in the exceptionPayload attribute.
MuleMessage composition inside exception strategy
What is that? This doesn’t fit your need?. Well I have a gift for you. It’s called <custom-exception-strategy>. Using this element, you get all the features of <default-exception-strategy> plus you can define your own exception strategy implementation and manipulate the event before routing it and after routing it.
Working with transactions
As I mentioned before, Mule transactions are rollback by default when an exception is thrown. But, as always, you have the power. You can define when to commit or rollback a transaction using <commit-transaction> and <rollback-transaction>. These elements have an exception-pattern attribute where you can define for which exceptions the element applies.
Patterns you can use:
- java.lang.Exception – Matches only if the exception is exactly java.lang.Exception
- java.lang.Exception+ – Matches if the exception is java.lang.Exception or a subclass
- org.mule.routing.* – Matches any exception which names starts with org.mule.routing
- * – Matches any exception type
The rule is: If the exception-pattern in <rollback-transaction> matches then the transaction is rollback. If the exception-pattern in <rollback-transaction> doesn’t match and the <commit-transaction> exception pattern matches then the transaction is committed. Any other case the transaction is rollback.
Putting everything together
I showed you the behavior of Mule exceptions strategy in detail. Now you know how to process exception inside a flow, what MuleMessage looks like inside the exception strategy and after returning from it, what is the default behavior of exception strategy and how to manage transactions. Now you should be able to handle error inside Mule.
That’s not enough for you? Then stay tuned for the next post about exception strategy patterns. We are going to get much more action by showing you how to implement most common error handling scenarios.