10.1 Mule 4 Error Object Hierarchy & Custom Error Types
Key Takeaways
- The Mule 4 Error Object (error) is automatically instantiated upon exception occurrence and contains critical diagnostic properties including error.description, error.detailedDescription, error.errorType, error.errorMessage, and error.childErrors.
- The Error Type hierarchy forms a taxonomy tree rooted at ANY, allowing hierarchical matching where catching broad types (e.g., HTTP:ANY or ANY) catches all specialized subtypes (e.g., HTTP:CONNECTIVITY or HTTP:NOT_FOUND).
- The CRITICAL branch of the hierarchy (e.g., FATAL_JVM_ERROR, OUT_OF_MEMORY, OVERLOAD) encompasses fatal system-level errors that cannot be intercepted, handled, or suppressed by application error handlers.
- The error.errorMessage property preserves the complete MuleMessage (payload and attributes) returned by failing downstream systems (such as HTTP 4xx/5xx responses), while error.childErrors holds route-level failures from composite routers like Scatter-Gather.
- Custom error types are defined dynamically using the <raise-error> component with the type="CUSTOM_NAMESPACE:IDENTIFIER" syntax and inherit automatically from the root ANY error type.
Mule 4 Error Object Hierarchy & Custom Error Types
In Mule 4, error handling is fundamentally re-architected around an explicit, declarative, and type-safe error handling framework. Unlike earlier Mule versions or traditional Java-based frameworks that rely on low-level Java exception classes, Mule 4 abstracts failures into a structured Error Object and a declarative Error Type Hierarchy. Understanding the composition of the Error Object, how error namespaces operate, and how to define and raise custom business errors is a foundational requirement for the Salesforce Certified MuleSoft Developer I examination.
1. Mule 4 Error Object Architecture
Whenever a message processor, connector operation, or routing component throws an exception during message processing, the Mule runtime intercepts the failure, halts normal sequential flow execution, and instantiates an immutable Error Object bound to the keyword error.
+---------------------------------------------------------------------------------------------------+
| MULE 4 ERROR OBJECT STRUCTURE |
| |
| error |
| | |
| +--- description : String ("HTTP GET on 'https://api.acme.com/v1/users' failed") |
| +--- detailedDescription : String ("HTTP GET on resource failed with status code 404") |
| +--- exception : Object (Underlying Java Exception / Stack Trace) |
| +--- childErrors : Object (Map of child Error Objects, e.g. in Scatter-Gather) |
| | |
| +--- errorType : Object (Complex Error Type Definition) |
| | +--- namespace : String ("HTTP") |
| | +--- identifier : String ("NOT_FOUND") |
| | +--- parentErrorType : Object (Reference to parent type: HTTP:ANY -> ANY) |
| | |
| +--- errorMessage : MuleMessage (Response message emitted by the failing target) |
| +--- payload : Object ({ "code": "USER_NOT_FOUND", "message": "User #88..." })|
| +--- attributes : Object ({ statusCode: 404, headers: { ... } }) |
+---------------------------------------------------------------------------------------------------+
Key Properties of the error Object
| Property | Data Type | Description & Practical Usage |
|---|---|---|
error.description | String | A concise, human-readable summary of the error (e.g., "HTTP GET on resource failed: Not Found (404)"). Ideal for standard log output. |
error.detailedDescription | String | A more exhaustive diagnostic description of the failure, often including URI paths, query parameters, or internal component states. |
error.errorType | Object | A structured object describing the exact classification of the error within the Mule taxonomy. Contains namespace, identifier, and parentErrorType. |
error.errorType.namespace | String | The domain or module that originated the error (e.g., "HTTP", "DB", "VALIDATION", "MULE", or a custom business namespace like "ORDER"). |
error.errorType.identifier | String | The specific failure classification within the namespace (e.g., "CONNECTIVITY", "NOT_FOUND", "BAD_SQL_SYNTAX", "INVALID_BOOLEAN"). |
error.errorType.parentErrorType | Object | The immediate parent ErrorType in the hierarchy. For example, HTTP:NOT_FOUND has parent HTTP:CLIENT_SECURITY or HTTP:ANY, which in turn has parent ANY. |
error.errorMessage | MuleMessage | When a remote operation fails (such as an <http:request> returning an HTTP 4xx or 5xx response), error.errorMessage contains the actual MuleMessage returned by that remote server, preserving both error.errorMessage.payload (the backend error body) and error.errorMessage.attributes (e.g., response headers and status code). |
error.childErrors | Collection / Map | Contains child error objects when composite operations fail. Most notably populated when a <scatter-gather> router fails with MULE:COMPOSITE_ROUTING or when a <parallel-foreach> encounters route-level failures. |
error.exception | Object | The raw underlying Java exception instance and stack trace (primarily used for advanced debugging). |
[!IMPORTANT] Preserving Backend API Error Payloads via
error.errorMessageA very common certification exam scenario asks how to retrieve the exact JSON or XML error response sent by an external REST API when an<http:request>call fails with status 400, 404, or 500. In Mule 4, the external response payload is stored inerror.errorMessage.payload, NOT inerror.descriptionor the top-levelpayload. Accessingpayloadinside an error handler will reflect whatever payload was in the flow prior to the failing processor, unless explicitly overwritten.
2. Mule 4 Error Type Hierarchy
Mule 4 structures all error types into a single, unified taxonomy tree. At the highest level, errors are divided into two fundamental branches: ANY and CRITICAL.
[ ERROR ROOT ]
|
+--------------------+--------------------+
| |
[ ANY ] [ CRITICAL ]
(Catchable Errors) (Non-Catchable Errors)
| |
+--------------+--------------+ +-- FATAL_JVM_ERROR
| | | +-- OUT_OF_MEMORY
[ CORE TYPES ] [ CONNECTORS ] [ CUSTOM TYPES ] +-- OVERLOAD
| | |
+-- EXPRESSION +-- HTTP +-- ORDER:INVALID_ITEM
| | +-- CONNECTIVITY
+-- ROUTING | +-- NOT_FOUND
| +-- COMPOSITE_ROUTING
| +-- DB
+-- SECURITY +-- CONNECTIVITY
| +-- CLIENT_SECURITY
| +-- VALIDATION
+-- TRANSFORMATION +-- INVALID_BOOLEAN
The ANY Hierarchy (Catchable Errors)
ANY is the root type of all catchable errors. Any error handler configured with type="ANY" will intercept any error falling under this branch, regardless of the connector, module, or custom namespace.
The CRITICAL Hierarchy (Non-Catchable Errors)
CRITICAL errors represent fatal, unrecoverable system or JVM-level failures where runtime stability is compromised. CRITICAL errors cannot be handled or caught by <on-error-continue> or <on-error-propagate> scopes. When a CRITICAL error occurs, Mule logs the failure and immediately halts execution.
Standard CRITICAL error types include:
FATAL_JVM_ERROR: An unrecoverable JVM crash or internal error.OUT_OF_MEMORY: The JVM has exhausted its heap space.OVERLOAD: The system is overloaded and unable to allocate threads or memory buffers.
3. Core Built-In Error Namespaces and Identifiers
Mule 4 standardizes error types using the format NAMESPACE:IDENTIFIER. All namespaces and identifiers are uppercase.
Built-in Core and Connector Error Taxonomy
| Namespace | Error Type | Hierarchy / Parent | Cause & Trigger Condition |
|---|---|---|---|
MULE | MULE:ANY | ANY | Root error type for all core Mule runtime errors. |
MULE | MULE:EXPRESSION | MULE:ANY | A DataWeave expression failed evaluation (e.g., null pointer, invalid coercion, divide by zero). |
MULE | MULE:ROUTING | MULE:ANY | An issue occurred while routing a message. |
MULE | MULE:COMPOSITE_ROUTING | MULE:ROUTING | One or more routes in a <scatter-gather> failed. Child errors accessible via error.childErrors. |
MULE | MULE:STREAM_MAXIMUM_SIZE_EXCEEDED | MULE:ANY | A non-repeatable stream exceeded the in-memory or disk buffer size limit. |
MULE | MULE:REDELIVERY_EXHAUSTED | MULE:ANY | A message has exceeded its configured max redelivery attempts. |
HTTP | HTTP:CONNECTIVITY | CONNECTIVITY | Connection to remote HTTP endpoint failed (DNS failure, connection refused, TCP timeout). |
HTTP | HTTP:NOT_FOUND | HTTP:CLIENT_SECURITY / ANY | The HTTP Request received a 404 Not Found response code. |
HTTP | HTTP:UNAUTHORIZED | HTTP:CLIENT_SECURITY | The HTTP Request received a 401 Unauthorized response code. |
HTTP | HTTP:FORBIDDEN | HTTP:CLIENT_SECURITY | The HTTP Request received a 403 Forbidden response code. |
HTTP | HTTP:BAD_REQUEST | HTTP:ANY | The HTTP Request received a 400 Bad Request response code. |
HTTP | HTTP:METHOD_NOT_ALLOWED | HTTP:ANY | The HTTP Request received a 405 Method Not Allowed response code. |
HTTP | HTTP:TIMEOUT | TIMEOUT | HTTP request timed out waiting for server response (responseTimeout exceeded). |
HTTP | HTTP:PARSING | MULE:TRANSFORMATION | Failed to parse HTTP request or response headers/body. |
DB | DB:CONNECTIVITY | CONNECTIVITY | Database connection pool exhausted or database server unreachable. |
DB | DB:BAD_SQL_SYNTAX | DB:ANY | SQL statement contains a syntax error, invalid table, or missing column. |
DB | DB:QUERY_EXECUTION | DB:ANY | Database query execution failed (e.g., primary key violation, constraint check failure). |
VALIDATION | VALIDATION:INVALID_BOOLEAN | VALIDATION:ANY | <validation:is-true> or <validation:is-false> evaluated to invalid state. |
VALIDATION | VALIDATION:NULL | VALIDATION:ANY | <validation:is-not-null> found a null value. |
VALIDATION | VALIDATION:EMPTY_COLLECTION | VALIDATION:ANY | <validation:is-not-empty-collection> received an empty array. |
APIKIT | APIKIT:BAD_REQUEST | MULE:VALIDATION | Incoming request fails RAML/OAS schema validation (returns HTTP 400). |
APIKIT | APIKIT:NOT_FOUND | MULE:ROUTING | No matching API resource path defined in the API specification (returns HTTP 404). |
APIKIT | APIKIT:METHOD_NOT_ALLOWED | MULE:ROUTING | HTTP method not permitted on the requested resource (returns HTTP 405). |
APIKIT | APIKIT:NOT_ACCEPTABLE | MULE:ROUTING | Accept header cannot be satisfied by API (returns HTTP 406). |
APIKIT | APIKIT:UNSUPPORTED_MEDIA_TYPE | MULE:ROUTING | Content-Type header not supported by API resource (returns HTTP 415). |
Generalization and Matching Rules
Because error types exist in a hierarchical taxonomy:
- An error handler matching
ANYwill match all errors above exceptCRITICAL. - An error handler matching
CONNECTIVITYwill catch bothHTTP:CONNECTIVITYandDB:CONNECTIVITY. - An error handler matching
HTTP:ANYwill catchHTTP:NOT_FOUND,HTTP:UNAUTHORIZED,HTTP:CONNECTIVITY, and all otherHTTP:*errors. - An error handler matching
HTTP:CLIENT_SECURITYwill catchHTTP:UNAUTHORIZEDandHTTP:FORBIDDEN.
4. Custom Error Types & The <raise-error> Processor
In real-world enterprise applications, business rule failures (e.g., insufficient account balance, customer not found, invalid inventory quantity) should be handled using the same declarative error mechanism as technical exceptions. Mule 4 enables developers to throw custom errors using the <raise-error> processor.
Declaring Custom Errors
<flow name="process-withdrawal-flow" doc:name="Process Withdrawal Flow">
<http:listener config-ref="HTTP_Listener_config" path="/accounts/{id}/withdraw" doc:name="Listener"/>
<!-- Validate Account Balance -->
<choice doc:name="Check Balance">
<when expression="#[vars.accountBalance < payload.amount]">
<!-- Raise Custom Business Error -->
<raise-error
type="ACCOUNT:INSUFFICIENT_FUNDS"
description="The account balance is insufficient for the requested withdrawal amount."
doc:name="Raise Insufficient Funds"/>
</when>
<otherwise>
<logger level="INFO" message="Funds verified. Processing transaction..." doc:name="Log OK"/>
</otherwise>
</choice>
<!-- Error Handler in Flow -->
<error-handler>
<!-- Catch specific custom error -->
<on-error-continue type="ACCOUNT:INSUFFICIENT_FUNDS" doc:name="Catch Insufficient Funds">
<set-payload value="#[{ 'error': 'DECLINED', 'message': error.description, 'type': error.errorType.identifier }]" doc:name="Set Payload"/>
<set-variable variableName="httpStatus" value="422" doc:name="Set 422 Status"/>
</on-error-continue>
<!-- Catch all other custom ACCOUNT errors -->
<on-error-propagate type="ACCOUNT:ANY" doc:name="Catch Other Account Errors">
<logger level="ERROR" message="#['General Account error: ' ++ error.description]" doc:name="Log Error"/>
</on-error-propagate>
</error-handler>
</flow>
Rules for Custom Error Types:
- Format: Must follow the
CUSTOM_NAMESPACE:IDENTIFIERpattern (e.g.,ORDER:ITEM_OUT_OF_STOCK,AUTH:EXPIRED_TOKEN). - Case Sensitivity: Both namespace and identifier must consist of uppercase letters, numbers, and underscores.
- Reserved Namespaces: You must not use reserved system namespaces (
MULE,HTTP,DB,FILE,WSC,VALIDATION,APIKIT, etc.) for custom errors. - Hierarchy Inheritance: Custom error types automatically become children of the root
ANYtype. They also automatically support theNAMESPACE:ANYwildcard (e.g., matchingACCOUNT:ANYcatchesACCOUNT:INSUFFICIENT_FUNDS,ACCOUNT:NOT_FOUND, etc.).
5. Inspecting Error Details in DataWeave
Inside error handler message processors (such as <ee:transform>, <set-payload>, or <logger>), developers can inspect the error object using DataWeave to construct standardized API error responses conforming to RFC 7807:
%dw 2.0
output application/json
---
{
timestamp: now(),
status: vars.httpStatus default 500,
errorType: {
namespace: error.errorType.namespace default "UNKNOWN",
identifier: error.errorType.identifier default "UNKNOWN",
canonicalName: (error.errorType.namespace default "UNKNOWN") ++ ":" ++ (error.errorType.identifier default "UNKNOWN")
},
message: error.description,
detailedMessage: error.detailedDescription,
backendResponse: error.errorMessage.payload default null,
failedRouteErrors: error.childErrors default null
}
6. Exam Watch: Core Error Hierarchy Scenarios
[!IMPORTANT] Accessing
error.errorMessage.payloadvspayloadWhen an HTTP Request operation fails with a 4xx/5xx status code, the response body from the remote server is placed inerror.errorMessage.payload. The top-levelpayloadvariable in the flow remains the payload that existed before the failing component executed.
[!WARNING] CRITICAL Errors Cannot Be Caught If an exam question asks what error handler scope intercepts a
MULE:FATAL_JVM_ERRORorMULE:OUT_OF_MEMORY, the answer is none.CRITICALerrors bypass all<error-handler>,<on-error-continue>, and<on-error-propagate>scopes.
[!TIP] Matching Order Hierarchy When an error occurs, Mule matches against the most specific type first. If an error handler has a scope matching
HTTP:CONNECTIVITYand a scope matchingCONNECTIVITY, anHTTP:CONNECTIVITYerror will matchHTTP:CONNECTIVITY. However, if the scopes are defined sequentially in the XML, Mule evaluates them in declaration order!
A Mule flow sends a GET request to an external customer REST service using an HTTP Request operation. The remote service returns an HTTP 404 Not Found status with the response body: { "code": "ERR_CUST_404", "message": "Customer ID 5542 does not exist." }. Inside the flow's error handler, which DataWeave expression accesses the JSON response body returned by the remote service?
A Mule application experiences severe system stress during peak load. Which of the following error types belongs to the CRITICAL hierarchy branch and therefore CANNOT be caught, intercepted, or suppressed by an On-Error Continue or On-Error Propagate scope?
A developer needs to validate incoming order items in a Mule flow. If an item is out of stock, the flow must halt processing and raise a custom business error with namespace INVENTORY and identifier OUT_OF_STOCK, along with an explanation message. Which XML component configuration correctly raises this error?
A flow contains an error handler with three declared scopes in the following order: Scope 1 handles HTTP:CONNECTIVITY, Scope 2 handles HTTP:ANY, and Scope 3 handles ANY. During flow execution, an HTTP Request component fails with an HTTP:UNAUTHORIZED error (status 401). How does Mule match and execute these error handling scopes?