Exception Handling in Mule 4 - mule

I have to define a global exception handler and for each flow I have to define the same set of exceptions I want to use global exception handling in Mule 4 , I am following below steps , please suggest/help to configure exception handling globally .
Under Global Configuration Elements ->I clicked on "Click Create Configuration"
2 .I defined default Error Handler in it .
Please find enclosed the screenshot for it .
Thanks

You can share an error handler in the XML view. Just add a ref attribute to the error-handler attribute pointing to the name of the global error handler.
Note that it is also better to use the XML to share. Flow logic is not clear with just screenshots.
Example:
<flow name="myFlow1">
...
<error-handler ref="Error_Handler">
</error-handler>
</flow>
<flow name="myFlow2">
...
<error-handler ref="Error_Handler">
</error-handler>
</flow>
<error-handler name="Error_Handler">
<on-error-propagate type="ANY">
<logger level="ERROR" doc:name="Log the error" message="An error happened!" />
</on-error-propagate>
</error-handler>

Related

Why I couldn't catch the error in subflow?

From the Main api, i call a subflow. I have defined error handler in the main flow and subflow.(mine is complex scenario)
Here is a simple flow design of what I'm trying;
From the main flow, within Async scope I call i subflow. Mainflow, itself has errorhandler.
Within reporting subflow, i call another subflow, which throws an 403 error.
I thought to handle that in reporting subflow. So i used, on error continue. I used log mediator there to see it gets executed or not.
But it is not.
Rather, from the main flow I get,log ' in main error handler'
I haven't defined any global error handlers.
Why is that?
Main flow
<flow name="post:\notifications:raml-config">
.................
<async doc:name="Async">
<try doc:name="Try">
<flow-ref doc:name="Call-Reporting-subFlow
name="reporting-subflow" />
<error-handler >
<on-error-propagate enableNotifications="true" logException="true" doc:name="On Error Propagate" doc:id="743fc7cb-38d4-4a0c-ab36-9105645ce710" >
<logger level="INFO" doc:name="Logger" doc:id="5d18eb33-780e-4353-b65f-b26eec88612a" message="in main errror handler"/>
............
</flow>
Subflow (reporting flow)
<sub-flow name-"reporting-subflow">
<try doc:name="Try" >
<flow-ref doc:name="getcontracts" name="get-details-subflow" />
<error-handler >
<on-error-continue enableNotifications="true" logException="true" doc:name="On Error Continue" type="HTTP:FORBIDDEN">
<logger level="INFO" doc:name="Logger" message="GOT 403 error"/>
<flow-ref doc:name="gettoken" name="getToken-subflow" />
</error-handler>
</try>
</sub-flow>
One of the below may be the reason:
We cannot define an error handling for a sub flow, we can do it only
for private flows and normal flows.
Even if the main flow has an error handler, the flow referred within
the Async scope will not be managed by this error handler. To solve
this:
make the flow referenced within the async error handler as a
private flow and define a error handling at flow level
or define global error handling at application level.

name attribute on exception strategy is only allowed on global exception strategies

I created a global exception strategy as below,
<choice-exception-strategy name="GlobalExceptionStrategy">
<catch-exception-strategy name="400:BadRequest" when="#[message.inboundProperties['http.status']=="400"]" doc:name="400:BadRequest">
<logger message="Caught error with code #[message.inboundProperties['http.status']] and reason #[message.inboundProperties['http.reason']] for query payload #[message.payloadAs(java.lang.String)]" level="ERROR" doc:name="Logger"/>
</catch-exception-strategy>
</choice-exception-strategy>
But why I am still getting the error like name attribute is required only on global exception strategy?
Error was in this line <catch-exception-strategy **name**="400:BadRequest" when="#[message.inboundProperties['http.status']=="400"]" doc:name="400:BadRequest">
Using doc:name in place of name works perfect!

Not able to access Jira Payload in JAVA (java.util.Arrays$ArrayList)

Here is my Flow information. Trying to GET one issue from JIRA and want to setup that issueID to another project. Here i want to use Custom Transformer and setup all objects using JAVA coding.
<jira:config name="Jira" connectionUser="XXXXXXX" connectionPassword="XXXXX" connectionAddress="http://XXXXXXX/rpc/soap/jirasoapservice-v2" doc:name="Jira">
<jira:connection-pooling-profile initialisationPolicy="INITIALISE_ONE" exhaustedAction="WHEN_EXHAUSTED_GROW"/>
<reconnect count="3"/>
</jira:config>
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
<flow name="jira-pocFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/input" doc:name="HTTP"/>
<jira:get-issues-from-jql-search config-ref="Jira" jqlSearch="id=MRT-75" maxNumResults="100" doc:name="Jira"/>
<set-variable variableName="payload" value="#[payload[0]]" doc:name="Variable"/>
<component class="JIRATransformer" doc:name="Java"/>
<jira:create-issue-using-object config-ref="Jira" doc:name="Jira" >
<jira:issue ref="#[message.payload]"/>
</jira:create-issue-using-object>
<logger level="INFO" doc:name="Logger"/>
</flow>
I am trying to access JIRA payload object but it's throwing me Error as Type Cast Exception.
#Override
public Object transformMessage(MuleMessage message, String outputEncoding)
throws org.mule.api.transformer.TransformerException {
ArrayList<com.atlassian.jira.rpc.soap.beans.RemoteIssue> list = new ArrayList(Arrays.asList(message.getPayload()));
for(RemoteIssue q : (List<RemoteIssue>) list){
System.out.println("Print AssigneeInfo:->"+q.getAssignee());
}
}
I am getting following Errors.
ERROR 2015-04-15 19:58:59,526 [[jira-poc].HTTP_Listener_Configuration.worker.01] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Component that caused exception is: DefaultJavaComponent{jira-pocFlow.component.887693985}. Message payload is of type: Arrays$ArrayList
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. java.util.Arrays$ArrayList cannot be cast to com.atlassian.jira.rpc.soap.beans.RemoteIssue (java.lang.ClassCastException)
JIRATransformer:29 (null)
2. Component that caused exception is: DefaultJavaComponent{jira-pocFlow.component.887693985}. Message payload is of type: Arrays$ArrayList (org.mule.component.ComponentException)
org.mule.component.DefaultComponentLifecycleAdapter:348 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/component/ComponentException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to com.atlassian.jira.rpc.soap.beans.RemoteIssue
at JIRATransformer.transformMessage(JIRATransformer.java:29)
at org.mule.transformer.AbstractMessageTransformer.transform(AbstractMessageTransformer.java:141)
at org.mule.transformer.AbstractMessageTransformer.transform(AbstractMessageTransformer.java:69)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
I tried to follow this Documentation URL but couldn't able to figure it out.
http://mulesoft.github.io/jira-connector/java/com/atlassian/jira/rpc/soap/beans/RemoteIssue.html
I want to Access this Payload and want to update some details from payload object here. I can access payload using MEL expression #[payload[0]] and it automatically coverts it to com.atlassian.jira.rpc.soap.beans.RemoteIssue but using Java code i am not able to type cast it.
Can you please help me to cast this object correctly so i can access the Payload here ?
Thanks.
There's a bug in your component.
This Arrays.asList(message.getPayload()) wraps the message payload into a list. But the message payload is already a List<RemoteIssues> so this wrapping is unnecessary.
If you look at the source code of the JIRA connector, you'll see that MuleSoft prefers late casting of the RemoteIssue. I suggest you do the same:
for (Object o : ((List) message.getPayload())) {
RemoteIssue ri = (RemoteIssue) o;
...
}

No serializer found for class org.mule.module.jersey.MuleResponseWriter$1 while using APIKit

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.

How to capture an exception using the regex-filter filter in Mule ESB

Currently I have a flow that exposes a REST service with a string as input parameter . I am using a regex -filter to ensure the format parameter as follows :
<http:inbound-endpoint doc:name="HTTP"
connector-ref="ciuServiceHTTPConnector" ref="ciuServiceHTTPEndpoint"
exchange-pattern="request-response" />
<logger level="INFO" doc:name="Logger" message="epale1 #[payload]"/>
<regex-filter pattern="^/api/person/(V|E)[0-9]{8}$"
doc:name="Regex" />
<logger message="epale2 #[payload]" level="INFO" doc:name="Logger"/>
<jersey:resources doc:name="REST" >
<component class="...resource.CiudadanoResource"/>
</jersey:resources>
I need to send the customer a message "Invalid or missing parameter" . For this I use a choice-exception-strategy and catch-exception-strategy and then call a Subflow and perform http:response-builder.
How can I throw an exception(type) when the regex-filter do not match?. It is possible to incorporate this behavior or should I change my flow?
Thanks for your help;
Wrap it in a message-filter, like this:
<message-filter throwOnUnaccepted="true">
<regex-filter pattern="^/api/person/(V|E)[0-9]{8}$"
doc:name="Regex" />
</message-filter>
See the official documentation for further details:
Check the Throw On Unaccepted box to throw an exception if a message
or event is not handled. The default when not checked is to not throw
an exception.