Skip to content

Commit 6ad2861

Browse files
authored
Merge pull request #27 from titans-of-code/master
Updated to Mule LTS 4.4.0. Also small updates to Readme and previous error to be more flexible.
2 parents 688e889 + 70e8226 commit 6ad2861

File tree

5 files changed

+247
-116
lines changed

5 files changed

+247
-116
lines changed

README.md

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# API Error Handler
22

3-
This error handler module processes any errors thrown in a flow and transforms to the correct JSON response body and HTTP status code for an API.
3+
The error handler module processes any errors thrown in a flow and transforms to the correct JSON response body and HTTP status code for an API.
4+
5+
*This requires the [MuleSoft Enterprise Maven Repository][mule-ee] to compile and use.*
46

57
All APIKit and HTTP exceptions are handled by the module and can be customized in the *Common Errors* tab. Additional error definitions can be added via dataweave in the *Custom Errors* tab.
68

@@ -106,6 +108,7 @@ The groupId value must be the appropriate Anypoint Org Id where the module is de
106108
<groupId>${groupId}</groupId>
107109
<artifactId>api-error-handler</artifactId>
108110
<version>${error-handler.module.version}</version>
111+
<classifier>mule-plugin</classifier>
109112
</dependency>
110113
```
111114

@@ -174,8 +177,7 @@ An example of the full error handler flow is shown below. This example uses the
174177
doc:name="On Error Continue">
175178
<module-error-handler-plugin:process-error
176179
doc:name="Process Error"
177-
doc:id="ca10a245-319b-40c4-b6af-7de5c2ca83de"
178-
customErrorDefinition="errors/customErrors.dwl" />
180+
doc:id="ca10a245-319b-40c4-b6af-7de5c2ca83de" />
179181
<set-variable
180182
variableName="httpStatus"
181183
value="#[attributes.httpStatus]"
@@ -234,7 +236,7 @@ The custom errors must be an *object of objects* with the fields below.
234236
- `reason`: Error reason phrase to send in JSON body response. This is a string.
235237
- `message`: Error details to send in JSON body response. A string is preferred for this field, but any type is allowed.
236238

237-
dataweave script is allowed in each field value. To access the error object in this definition, you use `error` as normal.
239+
Dataweave script is allowed in each field value. To access the error object in this definition, you use `error` as normal.
238240

239241
**Custom errors override common errors.** If you want to override a common error's status or reason, and not just the message, you would add an entry for that error in the custom errors definition, which will completely override the common error.
240242

@@ -245,13 +247,35 @@ A template custom error file, [examples/customErrors.dwl](./examples/customError
245247
- Unknown error handler: `MULE:UNKNOWN`. This is recommended when you want to propagate message and error code from non-standard errors, like `495`.
246248

247249
```
250+
/**
251+
* This provides custom error handling for the API Error Handler.
252+
*/
253+
248254
%dw 2.0
249255
output application/json
250-
251256
import * from module_error_handler_plugin::common
252257
253-
// Previous error nested in the Mule error object, which conforms to the API Error Handler responses.
254-
var previousError = getPreviousErrorMessage(error)
258+
/**
259+
* Previous error nested in the Mule error object.
260+
* Provides the entire payload of the previous error as a String.
261+
* Handles the main Mule Error formats to get nested errors:
262+
* - Composite modules/scopes, like Scatter-Gather, Parallel-Foreach, Group Validation Module
263+
* - Until-Successful
264+
* - Standard Error, like Raise Error, Foreach, and most connectors and errors.
265+
*/
266+
var previousError = do {
267+
var nested = [
268+
error.childErrors..errorMessage.payload, // Composite
269+
error.suppressedErrors..errorMessage.payload, // Until-Successful
270+
error.exception.errorMessage.typedValue // Standard Error: must go last because it has content if this is one of the other types of errors
271+
] dw::core::Arrays::firstWith !isEmpty($)
272+
---
273+
if (nested is Array)
274+
toString(nested map (toString($)) distinctBy $)
275+
else
276+
toString(nested)
277+
}
278+
255279
---
256280
{
257281
/*
@@ -305,7 +329,6 @@ var previousError = getPreviousErrorMessage(error)
305329
### Common Functions
306330
There are some common functions provided by the module that you can use in your custom errors definition. They are imported by `import * from module_error_handler_plugin::common`.
307331

308-
- `getPreviousErrorMessage`: Gets the downstream API's error message text when an error is returned from that API. This should only used when the called API uses this same error module. Any other response structure must be manually handled by dataweave. It takes the error object as a parameter. This is a great way to propagate errors up the API stack without losing the original error.
309332
- `getErrorTypeAsString`: Gets the string for the current Mule error type. This corresponds to the *keys* in the custom error object. Example: `HTTP:INTERNAL_SERVER_ERROR`.
310333
- `toString`: Converts any type to a string. If not a string, it uses write() with Java format. If empty, then returns empty string or the value specified in the second parameter.
311334

@@ -322,17 +345,13 @@ The error object definition takes the standard [Mule Error][mule-error] by defau
322345
### Use Previous Error
323346
Connectors usually generate error responses their own error responses and wrap the actual error response from the external system in the error object. This causes the external system's response to be lost and not propagated back to the API's caller. The previous error feature allows the module to retrieve the external system's error response from the error object and use that as the error message.
324347

325-
A common scenario is when a system API generates an error that needs to get propagated back to the caller of the experience or process API. Using normal error handling, like `error.description`, the SOAP fault or `500` response from the called system is not logged or propagated. These items are nested in the error object here: `error.exception.errorMessage.payload` and `error.exception.errorMessage.attributes`.
348+
A common scenario is when a system API generates an error that needs to get propagated back to the caller of the experience or process API. Using normal error handling, like `error.description`, the SOAP fault or `500` response from the called system is not logged or propagated. These items are nested in the error object here: `error.exception.errorMessage.typedValue.payload` and `error.exception.errorMessage.typedValue.attributes`. Be aware that payload and attributes won't be accessable by selector if the content is `Binary`. If the type is `Binary`, then you must read the error payload, `error.exception.errorMessage.typedValue`, as the correct MIME type if you want to access a specific field using a selector.
326349

327350
This feature will automatically replace the `message` field for ***all errors*** with the previous error defined by the provided dataweave if one exists. If the previous error does not exist or is empty, then it will leave the `message` field with its current value. This feature does not append the previous error to the current one. It simply replaces and is best used to propagate downstream errors up the API stack.
328351

329-
The dataweave should resolve to a string but any type is allowed. The default value below resolves to a called Mule API's error message, if the message is in `error.message` in the response body, which conforms to the API Error Handler responses.
330-
331-
```
332-
error.exception.errorMessage.payload.error.message default ''
333-
```
352+
The dataweave should resolve to a string but any type is allowed. You can override in any manner; the template custom error file gives a comprehensive example on how to convert nested errors to strings.
334353

335-
**Set this field to an empty string if you do not want to propagate previous errors.**
354+
**Set this field to an empty string if you do not want to propagate previous errors. This is the default value**
336355

337356
### Response Key Name for Payload
338357
This field allows you to customize the JSON key name where the error payload is set. This defaults to `error`, which is shown in the examples. This only supports changing the name of the top-level key; it does not change any other format. If you want the error payload to be the top-level element in the response, then set this field to empty string.
@@ -465,6 +484,7 @@ It takes the parameters below.
465484
./build.sh 43ae201-c97b-4665-9310-e3ac89ce1c28 deploy
466485
```
467486

487+
[mule-ee]: https://docs.mulesoft.com/mule-runtime/latest/maven-reference#configure-mulesoft-enterprise-repository
468488
[mule-error]: https://docs.mulesoft.com/mule-runtime/4.4/mule-error-concept
469489
[mule-error-types]: https://docs.mulesoft.com/mule-runtime/4.4/mule-error-concept#error_types
470490
[http-rfc-7231-6]: https://tools.ietf.org/html/rfc7231#section-6

examples/customErrors.dwl

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,32 @@
1+
/**
2+
* This provides custom error handling for the API Error Handler.
3+
*/
4+
15
%dw 2.0
26
output application/json
3-
47
import * from module_error_handler_plugin::common
58

6-
// Previous error nested in the Mule error object, which conforms to the API Error Handler responses.
7-
var previousError = getPreviousErrorMessage(error)
9+
/**
10+
* Previous error nested in the Mule error object.
11+
* Provides the entire payload of the previous error as a String.
12+
* Handles the main Mule Error formats to get nested errors:
13+
* - Composite modules/scopes, like Scatter-Gather, Parallel-Foreach, Group Validation Module
14+
* - Until-Successful
15+
* - Standard Error, like Raise Error, Foreach, and most connectors and errors.
16+
*/
17+
var previousError = do {
18+
var nested = [
19+
error.childErrors..errorMessage.payload, // Composite
20+
error.suppressedErrors..errorMessage.payload, // Until-Successful
21+
error.exception.errorMessage.typedValue // Standard Error: must go last because it has content if this is one of the other types of errors
22+
] dw::core::Arrays::firstWith !isEmpty($)
23+
---
24+
if (nested is Array)
25+
toString(nested map (toString($)) distinctBy $)
26+
else
27+
toString(nested)
28+
}
29+
830
---
931
{
1032
/*

pom.xml

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<groupId>ORG_ID_TOKEN</groupId>
66
<artifactId>api-error-handler</artifactId>
7-
<version>6.1.0</version>
7+
<version>6.2.0</version>
88
<packaging>mule-extension</packaging>
99

1010
<name>API Error Handler</name>
@@ -15,9 +15,9 @@
1515
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
1616

1717
<!-- XML SDK properties -->
18-
<mule.version>4.3.0</mule.version>
19-
<mule.extensions.maven.plugin.version>1.4.1</mule.extensions.maven.plugin.version>
20-
<app.runtime>4.3.0</app.runtime>
18+
<mule.version>4.4.0</mule.version>
19+
<mule.extensions.maven.plugin.version>1.5.1</mule.extensions.maven.plugin.version>
20+
<app.runtime>4.4.0</app.runtime>
2121
</properties>
2222

2323
<distributionManagement>
@@ -30,20 +30,20 @@
3030
</distributionManagement>
3131

3232
<dependencies>
33-
<!--Needed to discover the 'xml-based' XmlExtensionLoader for smart connectors -->
33+
<!--Needed to discover the 'xml-based' XmlExtensionLoader -->
3434
<dependency>
3535
<groupId>org.mule.runtime</groupId>
3636
<artifactId>mule-module-extensions-xml-support</artifactId>
3737
<version>${mule.version}</version>
3838
<scope>provided</scope>
3939
</dependency>
40-
<!-- DataWeave -->
40+
<!-- EE Dependency: Required for DataWeave -->
4141
<dependency>
4242
<groupId>com.mulesoft.mule.runtime.modules</groupId>
4343
<artifactId>mule-module-spring-config-ee</artifactId>
4444
<version>${mule.version}</version>
4545
<scope>provided</scope>
46-
</dependency>
46+
</dependency>
4747
</dependencies>
4848

4949
<build>
@@ -55,6 +55,20 @@
5555
<version>${mule.extensions.maven.plugin.version}</version>
5656
<extensions>true</extensions>
5757
</plugin>
58+
59+
<!-- MUnit: Definition is required even if MUnit is not used -->
60+
<plugin>
61+
<groupId>com.mulesoft.munit</groupId>
62+
<artifactId>munit-extensions-maven-plugin</artifactId>
63+
<dependencies>
64+
<dependency>
65+
<!-- Ensure using correct version for runtime. This plugin may not have latest in its POM. -->
66+
<groupId> org.mule.runtime</groupId>
67+
<artifactId>mule-core</artifactId>
68+
<version>${mule.version}</version>
69+
</dependency>
70+
</dependencies>
71+
</plugin>
5872
</plugins>
5973
</build>
6074

@@ -65,12 +79,6 @@
6579
<url>https://repository.mulesoft.org/releases/</url>
6680
<layout>default</layout>
6781
</repository>
68-
<repository>
69-
<id>mulesoft-snapshots</id>
70-
<name>MuleSoft Snapshots Repository</name>
71-
<url>https://repository.mulesoft.org/snapshots/</url>
72-
<layout>default</layout>
73-
</repository>
7482
<repository>
7583
<id>anypoint-exchange-v3</id>
7684
<name>Anypoint Exchange V3</name>
@@ -79,17 +87,4 @@
7987
</repository>
8088
</repositories>
8189

82-
<pluginRepositories>
83-
<pluginRepository>
84-
<id>mulesoft-releases</id>
85-
<name>MuleSoft Releases Repository</name>
86-
<url>https://repository.mulesoft.org/releases/</url>
87-
</pluginRepository>
88-
<pluginRepository>
89-
<id>releases-ee</id>
90-
<name>Mule Release Repository</name>
91-
<url>https://repository.mulesoft.org/nexus/content/repositories/releases-ee/</url>
92-
</pluginRepository>
93-
</pluginRepositories>
94-
9590
</project>

0 commit comments

Comments
 (0)