I define a flow. It publishes a Web Service with CXF, exchange-pattern: request-response. The Service defines/throws exception type: CAEService_Exception. The web service implementation is almost a dummy. The ws request is processed by other message processors in the flow. During the flow, other components or the ESB itself could throw different exceptions, e.g. ConnectionException, ApplicatOneException, or CompnentTwoException what forever.
In such case, it is important to throw only (business exception) the CAEService_Exception to the client!
How to get(catch) the different exceptions, and how to process/handle them so that the CXF module throws CAEService_Exception to client?
Thanks for your advice!
Regards
Dianlong
<flow name="CAEService" doc:name="CAEService">
<http:inbound-endpoint address="${http.host.inbound}/ebiz/ws/CAEService" exchange-pattern="request-response" doc:name="HTTP">
<cxf:simple-service serviceClass="org.mule.j2a.ws.cae.CAEService"/>
</http:inbound-endpoint>
<component class="org.mule.j2a.ws.cae.CAEServiceImpl" doc:name="Java"/>
<flow-ref name="Fest_ERPs" doc:name="Sub Flow with transformers, call other services, etc."/>
<!-- exceptions -->
</flow>
You can use a choice-exception-strategy to catch the different ones.
eg
<flow name="Sample_Flow">
...
<choice-exception-strategy doc:name="Choice Exception Strategy">
<catch-exception-strategy doc:name="Catch Exception Strategy"/>
<rollback-exception-strategy doc:name="Rollback Exception Strategy"/>
</choice-exception-strategy>
</flow>
and then throw something else to the client in there respecive implementatinos
<catch-exception-strategy name="Catch_Exception_Strategy">
-- do you stuff
</catch-exception-strategy>
Related
How to find Http error payload in exception object ?
System 1 -> Call's Mule server . Mule server -> Docusign / some one else.
Docusign / some one returns 400 error with json payload (includes errorCode etc)
I need to return the exact details back to System 1.
how will i do this?
1) I did try to add all codes in success codes 200..599, then even error is having 200 ok . This will cause more problem, because I have to add lot of choice routing as some flows are having more data conversion.
2) Ideal soln -> Raise exception as usual. This has to be caught in choice exception. Now I have to send the same status_code and the json response back to the caller.
Issue -? how can i find the payload returned by HTTP in exception object. Where is stored in exception object.
Here is the sample- one way of handling this kind of scenario , use validation Component to throw exception and capture in your mainflow either by exceptionHandling or by APIKIT ExceptionHandling
<flow name="routeexceptionFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/test" doc:name="HTTP"/>
<logger level="INFO" doc:name="Logger"/>
<http:request config-ref="HTTP_Request_Configuration" path="/in" method="POST" doc:name="HTTP">
<http:success-status-code-validator values="200..599"/>
</http:request>
<validation:is-false config-ref="Validation_Configuration" message="#[payload]" exceptionClass="nz.co.exception.BadRequestException" expression="#[message.inboundProperties['http.status'] ==400]" doc:name="Validate Bad Request"/>
<validation:is-false config-ref="Validation_Configuration" message="#[payload]" expression="#[message.inboundProperties['http.status'] !=200]" doc:name="Capture all other Exceptions"/>
<choice-exception-strategy doc:name="Choice Exception Strategy">
<catch-exception-strategy when="#[exception.causeMatches('nz.co.exception.BadRequestException')]" doc:name="Catch Exception Strategy">
<set-payload value="#[exception.message]" doc:name="Set Payload"/>
<logger level="INFO" doc:name="Logger"/>
</catch-exception-strategy>
<catch-exception-strategy doc:name="Catch Exception Strategy">
<logger message="****log all other exception****" level="INFO" doc:name="Logger"/>
</catch-exception-strategy>
</choice-exception-strategy>
</flow>
Add this class in your java folder
package nz.co.exception;
public class BadRequestException extends Exception {
private static final long serialVersionUID = 8546839078847602529L;
public BadRequestException() {
super();
}
public BadRequestException(String message) {
super(message);
}
public BadRequestException(Throwable t) {
super(t);
}
public BadRequestException(String message, Throwable t) {
super(message, t);
}
}
In your project if you are using APIKIT Router , then instead of using exceptionHandling as above, add directly nz.co.exception.BadRequestException in 400 ReturnCode apikitExceptionHandling.
asking this for some mulesoft expertise.
the following exception mapping strategy is supposed to branch on hhtp.status 401, 403, 429 but keeps on falling into the 401 branch for status codes 401 and 403 (at least, and determined by both debugging and log written to console):
<apikit:mapping-exception-strategy doc:name="waysact-adaptor-main-exception-strategy">
<apikit:mapping statusCode="401">
<apikit:exception value="org.mule.module.http.internal.request.ResponseValidatorException"/>
<logger message="psc>>> logging 401 = #[payload]" level="INFO" doc:name="log-http-401"/>
</apikit:mapping>
<apikit:mapping statusCode="403">
<apikit:exception value="org.mule.module.http.internal.request.ResponseValidatorException"/>
<logger message="psc>>> logging 403 = #[payload]" level="INFO" doc:name="log-http-403"/>
</apikit:mapping>
<apikit:mapping statusCode="429">
<apikit:exception value="org.mule.module.http.internal.request.ResponseValidatorException"/>
<logger message="psc>>> logging 429 = #[payload]" level="INFO" doc:name="log-http-429"/>
</apikit:mapping>
<apikit:mapping statusCode="400">
<apikit:exception value="org.mule.module.http.internal.request.ResponseValidatorException"/>
<logger message="psc>>> logging anything = #[payload]" level="INFO" doc:name="logging-anything"/>
</apikit:mapping>
</apikit:mapping-exception-strategy>
is this because it is branching only on exception type org.mule.module.http.internal.request.ResponseValidatorException? i thought it was meant to branch on the status code?
there is another strategy, choice-exception-strategy, that should branch on different exception object types.
Branching of exception based on http.status can be defined with choice exception strategy as below example,
<choice-exception-strategy doc:name="Choice Exception Strategy">
<catch-exception-strategy when="#[message.inboundProperties.'http.status'=='404']" doc:name="Catch Exception Strategy" >
<logger message="Exceptions message is ... #[exception.message]" level="ERROR" doc:name="exceptionLogger"/>
<set-variable variableName="exceptionMessage" value="#[exception.message]" doc:name="Set exceptionMessage"/>
<set-payload value="{ errors: { errorCode: #[message.inboundProperties.'http.status'], errorMessage: #[flowVars.exceptionMessage] } }" doc:name="Set Exception Payload"/>
</catch-exception-strategy>
<catch-exception-strategy doc:name="Catch Exception Strategy" >
<logger message="Exception message is ... #[exception.message]" level="ERROR" category="com.project.stacktrace" doc:name="exceptionLogger"/>
<set-variable variableName="exceptionMessage" value="#[exception.message]" doc:name="Set exceptionMessage"/>
<set-payload value="{ errors: { errorCode: #[message.inboundProperties.'http.status'], errorMessage: #[flowVars.exceptionMessage] } }" doc:name="Set Exception Payload"/>
</catch-exception-strategy>
</choice-exception-strategy>
APIkit matches the exception based on the exception value defined and not by the statusCode defined. Use choice exception strategy and define multiple catch exception strategy in it. Make sure each catch exception strategy matches a unique exception to make the way for proper http.status code and desired exception payload.
For example, if you want to have 400 to be thrown, make sure a catch exception strategy matches BadrequestException. If the status codes are coming out of the HTTP requester, match the ResponseValidatorException and set the incoming http.status and exception payload
I'm developing a mule work-flow to insert a record into the database, trying to catch the exception in case if the record is already present and send the HTTP status (409-Conflict) and the back to the client.
<when expression="#[message.inboundProperties['http.method'] == 'POST']">
<json:json-to-object-transformer returnClass="java.lang.Object" doc:name="JSON to Object" />
<set-variable variableName="id" value="#[message.payload.id]" doc:name="Save brandId"/>
<json:object-to-json-transformer doc:name="Object to JSON"/>
<db:insert config-ref="Postgres" doc:name="Configstore">
<db:parameterized-query><![CDATA[INSERT INTO messages("id", "data") VALUES ( #[flowVars['id']], CAST(#[message.payload] as json))]]> </db:parameterized-query>
</db:insert>
<logger message="REST Response = #[message.payload]" level="INFO" doc:name="LOG Rest Response"></logger>
<choice-exception-strategy name="Global_Choice_Exception_Strategy" doc:name="Global Choice Exception Strategy">
<catch-exception-strategy doc:name="Catch_Exception_Strategy" when="#[exception.causedBy(org.postgresql.util.PSQLException)]">
<set-payload value="The request cannot be processed, the error is #[exception.getExceptionPayload()]"/>
<set-property propertyName="http.status" value="404"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" method="POST" doc:name="HTTP"/>
</catch-exception-strategy>
</choice-exception-strategy>
</when>
The start-up is repeatedly failing and the following error reported in the logs.
cvc-complex-type.2.4.a: Invalid content was found starting with element 'choice-exception-strategy'. One of '{"http://www.mulesoft.org/schema/mule/core":abstract-message-processor, "http://www.mulesoft.org/schema/mule/core":abstract-outbound-endpoint, "http://www.mulesoft.org/schema/mule/core":abstract-mixed-content-message-processor}' is expected.
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source) ~[?:?]
This error alternatively reported for both choice-exception-strategy and catch-exception-strategy. Not sure what's invalid here or need to define a custom message-processor or outbound-endpoint. I'm using mule EE-3.8.0
The problem is that you are using an exception strategy within a choice element. The exception strategy must be defined for your whole flow, not single elements (some do allow them though but are rare cases). You can find more on this here and an example here.
HTH
I'm new to Mule and while working on a fairly simple Hello World example on Anypoint Studio to test out the Scatter/Gather flow control element, I'm getting the following error, without much else in the way of information:
ERROR 2014-12-19 22:00:30,172 [[unifinesb].connector.http.mule.default.receiver.02] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Exception was found for route(s): 0. Message payload is of type: String
Type : org.mule.routing.CompositeRoutingException
Code : MULE_ERROR--2
JavaDoc : http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/routing/CompositeRoutingException.html
Payload : /Waldo
********************************************************************************
Exception stack is:
1. Exception was found for route(s): 0. Message payload is of type: String (org.mule.routing.CompositeRoutingException)
org.mule.routing.CollectAllAggregationStrategy:51 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/routing/CompositeRoutingException.html)
********************************************************************************
Root Exception stack trace:
org.mule.routing.CompositeRoutingException: Exception was found for route(s): 0. Message payload is of type: String
at org.mule.routing.CollectAllAggregationStrategy.aggregateWithFailedRoutes(CollectAllAggregationStrategy.java:51)
at org.mule.routing.CollectAllAggregationStrategy.aggregate(CollectAllAggregationStrategy.java:38)
at org.mule.routing.ScatterGatherRouter.processResponses(ScatterGatherRouter.java:207)
at org.mule.routing.ScatterGatherRouter.process(ScatterGatherRouter.java:135)
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:24)
at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:58)
at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:44)
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:24)
at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:44)
at ...
Judging from the top description of the error, I understand the problem to be that Scatter gather does not receive String payloads, even though the current documentation for the component mentions nothing of the sort. Is this correct?
The flow I'm running is fairly simple, receiving a String from an inbound http and trying to route it to a REST service that will use the String to print something (returning text/plain) and to a DB to store the String in a table. Relevant code follows:
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8084" doc:name="HTTP"/>
<expression-filter expression="#[payload != '/favicon.ico']" doc:name="Filter browser icon padding"/>
<logger message="current payload is #[payload]" level="INFO" doc:name="Startup log - to stdout"/>
<scatter-gather doc:name="Scatter-Gather">
<processor-chain>
<logger message="#['Rest branch msg input :' + payload]" level="DEBUG" doc:name="File Logger"/>
<http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:8080/application/rest/mensaje?givenName=#[payload]" doc:name="REST Service"/>
<logger message="#['Rest msg output :' + payload]" level="DEBUG" doc:name="File Logger"/>
</processor-chain>
<processor-chain>
<logger message="#['Database msg input :' + payload]" level="DEBUG" doc:name="File Logger"/>
<db:insert config-ref="MySQL_VestaLocal" doc:name="Application Postgress">
<db:parameterized-query><![CDATA[insert into http_user_info (first_name) values ('#[payload]');]]></db:parameterized-query>
</db:insert>
<logger message="#['Database msg output :' + payload]" level="DEBUG" doc:name="File Logger"/>
</processor-chain>
</scatter-gather>
<set-payload value="#['REST DB Success!']" doc:name="Set Payload"/>
Trawling through the net I found this old Mule JIRA issue with an exception similar to what I'm getting, but trying out the suggested solution (workaround?) didn't do anything for me: https://www.mulesoft.org/jira/browse/MULE-7594
Something wrong is happening in your route 0.
You are getting a composite routing exception as per documentation:
The CompositeRoutingException is new to the 3.5.0 Runtime. It extends
the Mule MessagingException to aggregate exceptions from different
routes in the context of a single message router. Exceptions are
correlated to each route through a sequential ID.
This exception exposes two methods which allow you to obtain the IDs
of failed routes and the exceptions returned by each route.
The getExceptions method returns a map where the key is an integer
that identifies the index of the failed route, and the value is the
exception itself. The getExceptionForRouteIndex(int) method returns
the exception of the requested route ID.
As you don't have an execption strategy, the toString is call to that exception and that only prints the route failing (that has nothing to do with the fact that the payload is String)
Please use the following exeption strategy to find out exactly what's wrong:
<catch-exception-strategy doc:name="Catch Exception Strategy">
<logger level="ERROR" message="#[exception.exceptions]"/>
</catch-exception-strategy>
When I use APIKit router with a Rest(jersey) component, I am getting a exception( as below), this exception does not occur when I use a flow-ref instead of the API Router ( Inserted flow snippet below). Any clues ?
Message : No serializer found for class org.mule.module.jersey.MuleResponseWriter$1 and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (org.codehaus.jackson.map.JsonMappingException)
Code : MULE_ERROR--2
Exception stack is:
1. No serializer found for class org.mule.module.jersey.MuleResponseWriter$1 and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (org.codehaus.jackson.map.JsonMappingException)
org.codehaus.jackson.map.ser.impl.UnknownSerializer:52 (null)
2. No serializer found for class org.mule.module.jersey.MuleResponseWriter$1 and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (org.codehaus.jackson.map.JsonMappingException) (org.mule.api.transformer.TransformerException)
org.mule.module.json.transformers.ObjectToJson:103
<flow name="main" doc:name="main">
<http:inbound-endpoint doc:name="HTTP" exchange-pattern="request-response" host="localhost" port="9081"/>
<logger level="INFO" doc:name="Logger"/>
<apikit:router config-ref="apiConfig" doc:name="APIkit Router"/>
<exception-strategy ref="apiKitGlobalExceptionMapping" doc:name="Reference Exception Strategy"/>
</flow>
<flow name="wine-cellar-muleFlow1" doc:name="wine-cellar-muleFlow1">
<jersey:resources doc:name="REST">
<component class="WineResource"/>
</jersey:resources>
<json:object-to-json-transformer doc:name="Object to JSON"/>
</flow>
I believe the class MuleResponseWriter has some fields which do not have public getters or setters.