Mule 4 error handling deep dive
The anticipation of jumping in for a deep dive, a little nervous, quite uncertain, and then you JUMP! Ahh, the water is great. We have learned the basics for the behavior of Error Handling in Part 1: Mule 4 Handling: Demystified, now it’s time to JUMP for a deep dive into how we can control errors when they occur for our desired outcome. You can create your own flows or download the example flows here.
Family of Errors - Hierarchy
Errors are categorized by the type of error it is and the relationship it has with the error types that fall under each category. As we look at the chart below, we can see there is a parent/child hierarchy relationship for the error types. ANY error type is the most general parent and we have used that error type to catch all errors in our examples thus far. From now on, we will be choosing specific error types to handle.
Override HTTP Listener default response settings
The HTTP Listener is set to the following default configurations:
● A success response
– The payload
– A status code of 200
● For an error response
– The error.description
– A status code of 500
To handle our errors, we must change this configuration to be able to return a meaningful error message in the payload and to return a specific HTTP status code. So, we configure the HTTP Listener as follows:
● A success response
– The payload
– A variable with the default value set to 200
● For an error response
– The payload
– A variable with the default value set to 500
Note: In our examples, the variable is httpStatus.
Changing the HTTP settings modifies our error response as we see from our example flow below, instead of error description, we are now receiving the payload contents. Notice our response to our client is the payload value that was set confirming “Flow Started”. Next, we will use the payload to return a more meaningful error message to our client by adding a On Error Propagate scope to the flow.
Flow Level Error Handling - On Error Propagate
In this example, we add an On Error Propagate scope to the flow error handling section. Inside the scope, we set the payload to a message of “Error Occurred” and we use ++ to concatenate this message to include the error.description.
Notice in the On Propagate scope we are catching ANY error type, the most general parent error types. You can use this to catch all errors regardless of their specific type.
In our response we are receiving the default HTTP status code of 500 Server Error and the payload containing a custom message. Next let’s see the behavior of the On Error Continue scope!
Flow Level Error Handling - On Error Continue
Next we will create an example using the On Error Continue scope to the flow error handling section. Inside the scope, we set the payload to a message of “Error Occurred” and we use ++ to concatenate this message to include the error.description.
In our response, we are receiving an HTTP status code of 200 OK and the payload. As far as the HTTP listener is concerned no error occurred, however the processors following the error are not executed. Again, we are catching ANY error type, but this time the response is a Success! What if we change from ANY to a specific error type?
Flow Level Error Handling - No Matching Error Type
In this example we changed the On Error Propagate scope to catch only STREAM_SIZE_EXCEEDED error types. This is a very important rule to understand for flow level error handlers!
When an error occurs (in our example it is ANY type error) and there is no error type match (STREAM_SIZE_EXCEEDED) in either On Error Propagate or On Error Continue, the Mule default Error Handler is invoked. You must have a match for all possible errors IF you want to catch the errors at the flow level, however there are other options that we will discuss in Part 3: Use case-specific error handling in Mule 4. But first, let’s take a look at how errors are handled when you have a child flow.
Parent-Child Flow Error Handling - On Error Propagate
We have a Parent flow that Flow References to the Child flow where the error occurs. Both the Parent and the Child flows have error handling scopes.
Follow the sequence of events below by number:
Parent flow executes to the Flow Reference and the Child flow executes until an error occurs.
ANY type error is raised and passed to the On Error Propagate scope.
On Error Propagate is catching ANY type of errors and the processors in the scope are executed.
The Error Message is sent to the Parent flow
ANY type error is raised in the Parent flow and passed to the On Error Propagate scope.
HTTP error response receives the error and returns to the client a 500 Server Error and the payload “Error occurred in Parent Flow”
Note: None of the remaining processors are executed in both the Child and Parent Flows.
Very busy processing! So we see the behavior of the Child flow throwing the error and the Parent flow rethrowing the error. Wondering about the On Error Continue behavior? Let’s see!
Parent-Child Flow Error Handling - On Error Continue
Again, we have a Parent flow that Flow References to the Child flow where the error occurs. Both Parent and Child flows have error handling scopes.
Follow the sequence of events below by number:
Parent flow executes to the Flow Reference and the Child flow executes until an error occurs.
ANY type error is raised and passed to the On Error Continue scope.
On Error Continue is catching ANY type of errors and the processors in the scope are executed.
The Mule Message is sent to the Parent flow, NO ERROR is detected. The remaining processors of the Parent flow ARE executed.
HTTP response is a success and returns to the client a 200 OK and the payload “Flow Completed” is rendered.
In cases where an error occurs in a Child flow that we are aware of by it being displayed in the logs (as we see above), but we want to continue executing the processors in the Parent flow, this design will work for us.
What if the HTTP Status code default values of 500 and 200, does not really reflect the type of error that is occuring?
Overriding HTTP Status Codes
There are MANY different HTTP status codes that will fully define our responses whether they are successful or failures. This is just a few of the Status Codes for your reference. As you noticed, we now have a variable in the HTTP Listener Status Code, this will allow us to set the variable to a Status Code that is better suited for the particular type of error that we are catching.
Default is 500, Set HTTP Status code to 400
Our first example is to set the httpStatus variable to 400. The error we are catching is a BAD_REQUEST and a 500 Server Error is not really accurate for this error. By setting it to 400, we have a response of Bad Request sent back to the client.
Set HTTP Status to 200
Our next example is to modify the behavior of the On Error Propagate. When we set the variable httpStatus to 200, the response will behave like On Error Continue! Depending on your desired outcome, you can Handle Errors through the HTTP Status codes. What about handling errors at the processor level? Next we will learn about the Try Scope equipped with error handling!
Error Handling at the Processor Level - Try Scope
When we have a need to handle an error at the level of a processor (or multiple processors) we can use the Try scope. Let’s add the Try scope to our Raise error processor and an On Error Continue scope to the Error handling section. In this example,we are using On Error Continue which does not flag an error and the flow continues to execute the remaining processors after the error. An error is logged, but the response is a Success 200 OK and the payload is returned to the client.
How was that deep dive?
Once we JUMPED, we landed deep into error handling techniques, behaviors, and strategies to handle the errors in a manner that will meet our requirements. Create or download the examples here so that you can practice variations of these strategies and behaviors. In Part 3: Use case-specific error handling in Mule 4 we will be including the Global Error handler (aka the Application Error handler) and customizing error types. Come on over, there is more fun ahead!