Error Handling Patterns in Mule

motif

Exception handling in event-driven systems like Mule can sometimes be a challenge because there are usually many more things happening at once, In this blog I will show you how to implement some common error handling patterns in Mule. We are going to cover the following use cases:

  • Route a message before exception through an exception strategy to a dead letter queue
  • Route an original message through an exception strategy to a dead letter queue
  • Route a message based on exception type


For more detailed information about how exception strategies work in Mule please see Getting the most out of Mule Error Handling blog post and Mule Error Handling documentation.

Note: All examples in this blog are presented using “Mule Flow” configuration architecture, since it’s now the preferred way to configure Mule applications, but the same information applies to the deprecated “Mule Service Model” architecture as well.

Mule’s default behavior during exception handling is to transform the payload being processed to a org.mule.message.ExceptionMessage which is constructed by the payload when the exception occurs and when the exception is thrown. Many times we don’t want to process ExceptionMessage inside the exception strategy so we must perform some transformation to achieve our goals.

Route message before exception through exception strategy to a dead letter queue

In this case we want to route the message being processed before the exception instead we have to transform the payload inside exception strategy.

Flow configuration: We will read a JMS message from queue in, then add some text and then force it to fail so the exception strategy is called and it sent the message to a DLQ and finally commit transaction.

[1] – For any exception type we want to commit the transaction so we don’t process this message again

[2] – Replace the current payload with the payload being processed before the exception was thrown using expression-transformer element

[3] – Send the message to a dead letter JMS queue. Do it joining the transaction started in the inbound endpoint. The commit will be done after routing the message through all the exception strategy message processors

Route original message through exception strategy to a dead letter queue

Very often the last state message before the exception is not enough. To accurately examine the problem and get to the root of the problem we need the original message received by the flow. So, once more, we need to do some transformation to our message to be able to route what we want.

Flow configuration: We will read a JMS message from queue in, then store the received message in a session property under the key originalMessage, after that modify the message adding some text to it and then force it to fail so the exception strategy is called and it restores the original message from the session property and send it to a DLQ and finally commit transaction.

[1] – To be able to preserve the original message we have to store it in a session property, that way we aren’t going to lose it despite what the rest of the flow does

[2] – For any exception type we want to commit the transaction so we don’t process this message again

[3] –Replace the current payload with the one saved in mule session properties

[4] – It’s important to remove the originalMessage session property to avoid propagate it to other flows, and thus avoid a performance hit by doing so. See the following blog for more information

[5] – Send the message to a dead letter JMS queue. Do it joining the transaction started in the inbound endpoint. The commit will be done after routing the message through all the exception strategy message processors.

 

Route message based on exception type

In this case we are going to show how to do content based routing base on the exception type using Mule Choice router

Flow configuration: We will read a JMS message from queue in, then force it to fail so the exception strategy is called and we route the exception message through different paths based on exception type.

[1] – First of all we define a maxRedelivery=”3″ of the inbound endpoint connector. Mule will only try to send the message through the flow a maximum of 3 times in case the message is causing the flow to throw an exception. After it fails for three times if Mule pick ups the same message again it will throw a MessageRedeliveredException. See Mule RedeliveryHandler for more information

[2] – We are using this element to only do a commit in case that the exception is of type org.mule.transport.jms.redelivery.MessageRedeliveredException

[3] – In case that the exception is of type MessageRedeliveredException then we don’t want to try to process it again, so we send the message being processed to a dead letter JMS queue and commit the transaction

[4] – In case that the exception was thrown by the Component then send the ExceptionMessage to the exceptions JMS queue

[5] – In any other case just log the exception

What next?

These are most used and simple scenarios for exception handling in mule. Next time I’m going to show you how to implement more complex scenarios such as stop flow execution in case of a critical exception or implement a custom exception strategy.

Blog Gotchas

  • <default-exception-strategy> and <custom-exception-strategy> can only have one message processor as child. To overcome this issue we use <processor-chain> element to be able to put more than one message processor
  • Sometimes we need to inspect the cause of the exception and not the exception itself to be able to determine the exact exception. This happens because mule wraps the thrown exception when it’s thrown by component or and endpoint.

 


We'd love to hear your opinion on this post


4 Responses to “Error Handling Patterns in Mule”

  1. Nice article!

    Since you are using single flow, you can also use flow variable(scope = “invocation”) to store original message. This way you dont need to delete session property at the end of flow. Isn’t it? if we have multiple flows and we want to retain original message then i believe session property is the only option.

    • Hi Mohit,

      You are right. You can use scope = “invocation” and it will work also. In fact, it would be much better than use session scope so the same property do not propagate to other flows, unless you actually need to do that.

      If you have multiple flows and want the original message from the first flow to be present in called flows then you need to use a session property. But if you want the original message property only available on the flow receiving the original message then scope invocation is what you need to use.

  2. […] my previous blog post Error Handling Patterns in Mule, in this post I will show you how to implement the following use […]

  3. Nice piece Pablo. Very useful.