Error handling in MuleSoft

Error Handling is the mechanism wherein the errors are controlled, and some flow is executed when Error occurs in the Mule Flow. If there is no error handling written at any of the levels, the Mule Default Error Handler is used, which stops the Flow and logs the console’s exception. If there is an error in the Flow, then the subsequent Flow will not get executed, and the Error is thrown. Error Handling adds a reform in the overall Mulesoft Architecture, making it seamless. MuleSoft Error handling best practices are explained in this Mule 4 Error Handling Blog. In Mule, we have various ways to deal with unexpected problems that may occur:
Default Error Handler at the Project Level: You can set up a general error handler for your entire project to manage errors that happen anywhere in your integration.
Custom Global Error Handler at the Project Level: If you want more control, you can create a custom error handler tailored to your project's specific needs.
Flow-Level Exception Handling: You can also handle exceptions on a per-flow basis using components like Raise Error, On-Error Continue, and On-Error Propagate.
Try Scope at the Flow or Processor Level: For even more granular control, you can use the Try scope to isolate and manage errors within specific parts of your flows or processors.
Error Object
These approaches give you flexibility in how you deal with unexpected issues in your Mule integration. When something goes wrong in a process, Mule creates an error object that holds information about the problem.
In Mule, the error object, often referred to as the Mule Error, encapsulates information about an error or exception that occurs during the processing of a message or event in a Mule flow. This error object typically holds the following key pieces of information:
- Error Type: The type or category of the error, such as MULE:EXPRESSION, HTTP:BAD_REQUEST, or CUSTOM:MY_CUSTOM_ERROR.
- Error Description: A human-readable description of the error, providing additional details about what went wrong.
- Error Code: A numeric or alphanumeric code associated with the error, which can be used for programmatic error handling.
- Payload: The payload of the error, which may contain specific error-related information or details about the message that caused the error.
- Detailed Error Information: Depending on the error type, additional information relevant to the specific error, such as stack traces or error-specific properties, may be included.
- Location Information: Information about where the error occurred in the flow, including the name of the flow, the component or processor that caused the error, and the line number if applicable.
Two types of Errors
System Errors: System errors are errors that occur outside of Mule flows.
Messaging Errors: Messaging errors that happen within a flow when there is some issue within the Mule Flow.
Three types of Error Handling in MuleSoft
- On Error Propagate: On Error Propagate catches the Error and process the Mule Flow inside the On Error Propagate block and return the error response (Status Code: 500).
- On Error Continue: On Error Continue catches the Error and processes the Mule Flow inside the On Error Continue and returns the success response (Status Code: 200).
- Try-Catch Scope: Try-Catch scope is used when we want to handle the errors in the inner components. A try-catch scope can be beneficial when we want to add a separate error processing strategy for various components in the Flow.
Developers often use the error object to implement error handling and exception management strategies in Mule flows. By inspecting the error type, description, or code, they can determine how to route or process messages differently based on the encountered error. This allows for graceful handling of exceptions and the ability to send appropriate responses or take corrective actions when errors occur during integration processes.
Real-Life Scenario Implementation
Step 1: Make Sure you have installed the latest version of MuleSoft Anypoint studio on your system.
Step 2: Create a new project in your MuleSoft Anypoint Studio by clicking on File>New>Mule Project.

Step 3: Name Your Project as Error_Handling_Implementation

Step 4: Add the file module by clicking on Add module in the mule pallet as Add Modules>Validation

Step 5: The Error Handling Components will be present by default under Core in Mule Palette.

Step 6: Let’s Create a Sample Flow.

- We will create a Listener which will listen at port 8081 (URL: http://localhost:8081/error).
- The next step is to add “Is not Null Validator“, which will only let the parameter pass, “is not null” and if the passed parameter is null, it will throw an error.
- After the Validator is completely configured, we will add a Logger which will Log a message “The Flow is Completed”.
- In The Validator referred to as “Is not Null”, we will configure the value to queryParams.name.
- To throw an error, we will not pass any queryParams to the URL, so that “Is not null” Validator throws an error.
Step 7: Flow for On Error Continue

Use On Error Continue

Inside the On Error Propagate Block, we have used a simple logger which will log simple message, i.e. “On Error Propagate Block”. After the “Is not Null” Validator will throw an Error, the subsequent Logger will not be executed. It will go to On Error Propagate Block and log the message written in the Logger to console and return the Error (“Value is Null”) response (Status Code: 500).
Output on Console after executing the following Flow:

Try- Catch Block
Try-Catch Block is by default present in the Core Module of Mule Palette.


Listener will listen on port 8081 (URL: http://localhost:8081/error) and process the request to the Try-Catch block. Since we are not passing any queryParams, So “Is not Null” Validator will throw an Error and the Error will go to On Error Continue Block and log the message. This is Try-Catch Block” and return Success status code, and the subsequent Logger will get executed and log the message as “Flow is completed”.

The error type is made up of two parts: the namespace and the identifier. Think of it like a category and a specific name. For example, it might be labeled as HTTP: UNAUTHORIZED where HTTP is the category and UNAUTHORIZED is the specific name of the issue.
Mule looks at this label to figure out what to do with the error. It then sends it to the right part of the system called the Error Handler, where there are specific instructions on how to deal with that type of error.
Flow Types And Error Handling Abilities
The difference between a flow, a sub-flow and a private flow, is that sub-flow doesn’t have an Error Handling scope. So, it's just flow and private flow are the ones that have an Error Handling block and can contain the On-Error Propagate and On-Error Continue.
Whether it is Propagate or Continue, Mule Executes all the components within those blocks. In Mule4, we can use On Error Continue, On Error Propagate, and Raise error at the flow level.
On-Error Continue
It is a type of error handler that allows a flow to continue processing even when an error occurs. It captures and logs the error but doesn't halt the flow's execution, enabling graceful handling of errors without breaking the overall integration process. Any transactions at this point are committed.
On-Error Propagate
It is an error handler that stops the flow's execution when an error occurs and propagates the error to higher-level error handlers or the calling process. It's used to handle and communicate errors effectively within an integration application. This rolls back any transaction.
Global Error Handling
You can create a special error handler that's not directly connected to any specific part of your application. This error handler can have instructions like On Error Continue or On Error Propagate to deal with errors. You can set this error handler as the default for your entire application in the global settings, so it works everywhere.
Then, in the main flow that contains the API kit router, you can refer to this error handler. So, whenever there's an error in that main flow, it will use the instructions you've set in the global error handler.
The most flexible approach is to put all error-handling instructions in a file called global-error-handler.xml. This is considered a good practice during development. Once we've caught an error, we can use information from it in different ways. We can send it as a response for an API, log it, or create an alert message to notify someone about the error. To get specific details from the error, we can find out what type of error it is and get its description. This helps us understand what went wrong.
What if we don't handle errors or don't set up error handlers? MuleSoft will use its default error handler. It will log the error and let it continue, which might not always be what we want.
Error Types
It's important to note that an error will only go to the Error Handling section if it's the same type of error that you've specified in your Error Handling setup. In Mule 4, there's a handy feature. It can figure out what types of errors might happen in a flow just by looking at the connectors you've used in that flow.
When you use components like HTTP Request and Database, Mule 4 can predict the kinds of errors that might happen based on how you've set up your flow.
Learning how On-Error Propagate and On-Error Continue works can make error handling easier. By following some rules, you can figure out what happens in your flow and what the result will be, like the payload and status code.
Process Of Error Handling
- Check the Error Handling Block: First, we look inside the error handling section of our Mule flow.
- Match the Error Type: If there's something in the error handling section, we check if it's set up to deal with the specific type of error that occurred (like on-error propagate or on-error continue).
- Default Handling: If there's nothing in the error handling section or if it doesn't match the error, Mule uses its default error handling.
- Response for Standalone Flows: If the flow isn't connected to other flows, Mule provides a default error response with a status code of 500 (if it hasn't been set differently). But if this flow is part of another flow, the error is sent back to that parent flow.
- Handling Matched Errors: If something is set up in the Error Handling section and it matches the error type, Mule follows those instructions to deal with the error.
In conclusion, effective error handling is a cornerstone of reliable Mule integration applications. By implementing comprehensive error handling strategies, organizations can ensure graceful error recovery, improved system resilience, and enhanced overall data integrity. Embracing error handling best practices empowers developers to create resilient integrations that can withstand unexpected challenges and provide uninterrupted services to users.