Error Handling In Mulesoft

Overview

When building integrations in MuleSoft, things can and will go wrong — APIs might be down, input data might be malformed, or a system might respond too slowly. That’s where error handling comes in. It’s not just about catching errors, but also about managing them gracefully to ensure your integrations remain robust, predictable, and easier to debug.

MuleSoft provides a flexible error-handling framework that lets developers manage different types of errors locally (within a flow) or globally (across the entire application). The goal is simple: keep your services reliable and make sure errors don’t become roadblocks.

Key Error Handling Components in MuleSoft

  • Raise error :
    Used to intentionally throw an error with a custom type and description. It’s useful for enforcing business logic rules or simulating errors during development or testing. Once triggered, the error flows into the appropriate error handler (Continue or Propagate).
  • On Error Continue:
    This scope always returns a successful (200 OK) response to the next level — even when an error occurs. It handles the error internally and prevents it from propagating further, allowing the flow to continue as if no error happened.
  • On Error Propagate:
    Always propagates the error to the next level and returns an error response to the next level. Error in the error handling block is not suppressed — instead, it’s passed up, and a 500 error response will be sent with the error message.

  • Error Handler :
    This component executes when an error is raised and routes it to the first matching handler inside it. It can contain multiple internal handlers (like On Error Continue and On Error Propagate) and supports matching errors by type or with a DataWeave expression. The raised error is stored as an inspectable object so handlers can act accordingly.

Implementation

On Error Continue

As part of this implementation, we intentionally call an endpoint that does not exist. This triggers an error, which is handled by the On Error Continue block. As a result, the error is caught and a success response is sent back to the parent flow. However, it’s important to note that any components placed after the step where the error occurred will not be executed — the control immediately jumps to the error handler.

Please refer to the video section below to see how the flow is designed. After that, we’ll discuss how control is transferred during error handling.

Based on the video shown above, we hope you’ve created a similar flow in your environment. Now, refer to the snapshot below to understand how the execution took place.

On Error Continue in Mulesoft

  • The flow begins with an API call, and a log message — “Main flow triggered !!!” — is printed. Next, the control is passed to a child flow using a Flow Reference.
  • Once the child flow is invoked, a log message — “Control received in Child-1-Flow” — is printed. In the following step, an error occurs during an HTTP Request call (or another operation), causing the flow to fail.
  • Since we have an On Error Continue block configured in the child flow, the error is caught and handled gracefully. The On Error Continue executes, treating the error as handled and returning a successful outcome.
  • Control then returns to the main flow, and the final log message is printed. Although the error details were set into the payload, the HTTP status code returned to the client (e.g., Postman) is still 200 OK, as the error was handled successfully inside the On Error Continue block.

⚠️ Important Note:

One thing you’ll notice in the On Error Continue configuration is that we’ve selected the error type as ANY. This means the On Error Continue block will catch and handle any type of error that occurs within child step.

Now, let’s consider a scenario where you select a specific error type, and an error of a different type occurs. In this case, the On Error Continue block will not be triggered. Instead, the error will be propagated to the parent flow.

If the parent flow does not have its own error handler and no Global Error Handler is configured, MuleSoft’s default error handler will take over. Although it’s not visible, this default handler behaves like On Error Propagate — meaning the error will not be suppressed and you’ll receive a 500 Internal Server Error in tools like Postman.

On Error Propagate

The ‘On Error Propagate’ step in Mule propagates the error that occurs within its scope to the parent flow or scope. The outcome is then determined by the error handling logic implemented at the parent level. Let’s see it in action.

If you’ve followed the previous steps, you should already have the global configuration in place. Now, create a new Mule configuration file named on-error-propagate.xml, and paste the XML content provided below into the configuration section. Once this is done, your flow should be designed and ready. Let’s now understand how the execution works.

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core"
	xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">
	<flow name="on-error-propagate-Main-Flow" doc:id="2efd459d-7f99-41fd-bb68-43cb599105ce" >
		<http:listener doc:name="Listener" doc:id="13c8a6d3-4d8c-4aba-931d-74aa0cb83004" config-ref="HTTP_Listener_config" path="/on-error-propagate">
		</http:listener>
		<logger level="INFO" doc:name="Logger" doc:id="ec4f0e57-525e-4a48-9054-d95dca4d3c71" message="Control is in Main flow!!"/>
		<flow-ref doc:name="Flow Reference" doc:id="53ec189d-e98f-44d2-a2d7-5fa94d49db5c" name="on-error-propagate-child-Flow"/>
	</flow>
	<flow name="on-error-propagate-child-Flow" doc:id="68baf755-96b0-44aa-89f9-9ace51eb844a" >
		<logger level="INFO" doc:name="Logger" doc:id="3a8382bd-8b0d-4fd7-80cd-8fa090b1d73b" message="Control received in child flow!!"/>
		<http:request method="GET" doc:name="Http request to unavailable endpoint" doc:id="84257128-b0e4-490f-8fe4-ecbd6a4c9475" config-ref="HTTP_Request_configuration" path="/pk"/>
		<error-handler >
			<on-error-propagate enableNotifications="true" logException="true" doc:name="On Error Propagate" doc:id="146c388c-b369-48c1-8aa3-43aa0f5d655f" type="ANY">
				<logger level="INFO" doc:name="Logger" doc:id="67cdec5f-470c-4ac4-b4eb-4db2d4507559" message="Control received in OnErrorPropagate section of the child flow!!"/>
				<set-payload value="#['Error returned from Child flow On-Error-Propagate section!!']" doc:name="Set Payload" doc:id="31c1b03b-e921-4a70-a2d3-3f93df716229" />
			</on-error-propagate>
		</error-handler>
	</flow>
</mule>

Based on the above snapshot, you might have noticed that when the child flow fails, control is passed to the ‘On Error Propagate’ block within the child flow. In that block, we’ve set the payload to 'Error returned from Child flow On-Error-Propagate section!!', but this message is not returned to the API invoker.

After the ‘On Error Propagate’ executes, the error is propagated to the parent (main) flow’s error handling section, and the flow continues with an error state. Since the main flow doesn’t have its own error handling defined, Mule checks for a Global Error Handler. However, as we haven’t defined any global error handler in this project, Mule’s default error handler takes over, and the flow terminates with an error.

Let’s invoke the API and see the result in  Postman.

If you observe the response body, you’ll notice that our Mule application has returned the error description thrown by the child flow. This happens because, in the Listener configuration, the error section is set up to return the error description.


Let’s change it to payload. You’ll notice that the payload set inside the On Error Propagate scope is now returned as the response to the client.


By now, you should have a clear understanding of how the response is sent to the client and how the On Error Propagate scope functions. Next, let’s add an On Error Continue to the main flow’s error handling. Set the error type to ANY and log a custom message. This time, you’ll notice that although an error occurs, the response body will contain the error details and the status code will be 200 OK. This happens because the error is handled within the On Error Continue, changing the status from error to success. If you want to override the payload within the On Error Continue, you can do so — and the modified payload will be sent to the client.

Raise error :

In MuleSoft, the Raise Error component is used to intentionally throw an error within a flow, allowing developers to control error scenarios and trigger custom error handling logic. It’s particularly useful in cases like input validation, business rule enforcement, or when a specific condition needs to interrupt the normal flow execution. The component requires an error type (formatted as namespace:identifier, such as APP:VALIDATION), and optionally accepts a description and cause, which help provide more context about the error. When the Raise Error step is executed, it halts the current flow and passes control to the nearest error handling scope, such as On Error Continue or On Error Propagate. This makes it a powerful tool for building resilient, maintainable integration logic with structured error management.

Create a mule flow and add below xml.

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core"
	xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">
	<flow name="raise-errorFlow" doc:id="afda6203-5c15-4fb4-bfb0-45c684e250e8" >
		<http:listener doc:name="Listener" doc:id="3c1d8828-60b8-429c-b84b-d2b262db8f2e" config-ref="HTTP_Listener_config" path="/raise-error"/>
		<logger level="INFO" doc:name="Logger" doc:id="afbd6cdd-793b-46e7-bfe3-094a2d22c343" message="Event received for custom raise exception!"/>
		<raise-error doc:name="Raise error" doc:id="a3fd7775-8901-470b-8c91-d83f97b30c7d" type="MULE:EXPRESSION" description="Intentionally thrown!"/>
		<logger level="INFO" doc:name="Logger" doc:id="f8a55cbd-6804-40f5-9a31-91f7149b903c" message="Logger after raise error step!"/>
		<error-handler >
			<on-error-propagate enableNotifications="true" logException="true" doc:name="On Error Propagate" doc:id="fe29506d-09f0-4ce0-8579-a339854b39fb" type="EXPRESSION">
				<logger level="INFO" doc:name="Logger" doc:id="c24ff613-e0a1-41fa-bc70-b327aa9ebede" message="Control received in error section"/>
			</on-error-propagate>
		</error-handler>
	</flow>
</mule>

This Mule flow is designed to simulate a controlled error scenario. It begins with an HTTP Listener configured to trigger on the /raise-error path. When a request hits this endpoint, the flow logs a simple message indicating that the event was received. Immediately after that, the Raise Error component throws a MULE:EXPRESSION type error with the message “Intentionally thrown!”. Because Raise Error halts the flow, the logger placed after it will never be executed. Instead, the flow jumps into the error-handler section, where an On Error Propagate block catches the error and logs another message: “Control received in error section”. This shows that the custom error was successfully handled and did not cause an unhandled failure.

To test this setup, simply start your MuleSoft application and send a GET request to http://localhost:<your-port>/raise-error from Postman or any API client. Upon hitting the endpoint, the flow will execute the Raise Error component, causing the flow to stop and move into the error handler. As a result, you will receive an error response in the body with details about the raised exception. The response will typically include the error type (MULE:EXPRESSION) and the custom message (“Intentionally thrown!”) you provided in the component. This confirms that the Raise Error component works as expected and that the error was successfully caught and handled within the same flow.

This pattern is widely used in real-world integrations to handle known failure scenarios gracefully, and it gives developers full control over how and when errors should be raised and processed.

✨ Hope you found this article informative!
If it helped you, share it with your friends or team — let’s spread the knowledge. 🙌
Cheers! 🚀

Leave a Comment