In my previous posi i explained how to call an endpoint using the call mediator. Usually when errors are thrown from the call mediator we can handle them using a custom sequence. When call mediators fails the execution stops hence handling errors is very essential.
For this post I will be modifying the same sequence which i created in the blog post [1]
The change which we need to do is we need to modify the sequence definition to map with the error sequence as shown below. You can find the modified sequence here.
<sequence xmlns="http://ws.apache.org/ns/synapse" name="countrySequenceWithError" onError="countryErrorSequence">
<property name="uri.var.countryCode" expression="$url:countryCode"/>
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>
<call blocking="true">
<endpoint>
<http method="get" uri-template="http://www.mocky.io/v2/597058891000001b0471d8fc/countryCode/{uri.var.countryCode}"/>
</endpoint>
</call>
<property name="uri.var.country" expression="json-eval($.country)"/>
<property name="uri.var.isfulltext" expression="json-eval($.fullText)"/>
<log level="full"/>
</sequence>
Then we need to create the sequence countryErrorSequence. Save the content in this link in a file and save it as countryErrorSequence.xml. You can modify the highlighted section with any error message which you like.
<?xml version="1.0" encoding="ISO-8859-1"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="countrySequence">
<log level="custom">
<property name="STATUS" value="Executing default 'fault' sequence"/>
<property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>
<property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>
</log>
<filter source="get-property('MESSAGE_FORMAT')" regex="soap1[1-2]">
<then>
<property name="SOAP_FAULT_CODE" value="Server"/>
<makefault>
<code expression="$ctx:SOAP_FAULT_CODE"/>
<reason expression="$ctx:ERROR_MESSAGE"/>
</makefault>
</then>
<else>
<payloadFactory>
<format>
<CountryDetailsError>
<code>$1</code>
<type>Error Encountered</type>
<message>An error occurred when trying to get the details of the requested country</message>
</CountryDetailsError>
</format>
<args>
<arg expression="$ctx:ERROR_CODE"/>
</args>
</payloadFactory>
<property name="messageType" value="application/json" scope="axis2"/>
</else>
</filter>
After saving the file you need to copy this file into the location wso2am-2.1.0/repository/deployment/server/synapse-configs/default/sequences/ if you are creating this API in the tenant mode then you need to copy this sequence to the location
wso2am-2.1.0/repository/tenants/{tenant_id}/synapse-configs/default/sequences
Further more you can handle custom error codes and provide different messages for them as well. The error codes returned can be found here.
For this post I will be modifying the same sequence which i created in the blog post [1]
The change which we need to do is we need to modify the sequence definition to map with the error sequence as shown below. You can find the modified sequence here.
<sequence xmlns="http://ws.apache.org/ns/synapse" name="countrySequenceWithError" onError="countryErrorSequence">
<property name="uri.var.countryCode" expression="$url:countryCode"/>
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>
<call blocking="true">
<endpoint>
<http method="get" uri-template="http://www.mocky.io/v2/597058891000001b0471d8fc/countryCode/{uri.var.countryCode}"/>
</endpoint>
</call>
<property name="uri.var.country" expression="json-eval($.country)"/>
<property name="uri.var.isfulltext" expression="json-eval($.fullText)"/>
<log level="full"/>
</sequence>
Then we need to create the sequence countryErrorSequence. Save the content in this link in a file and save it as countryErrorSequence.xml. You can modify the highlighted section with any error message which you like.
<?xml version="1.0" encoding="ISO-8859-1"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="countrySequence">
<log level="custom">
<property name="STATUS" value="Executing default 'fault' sequence"/>
<property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>
<property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>
</log>
<filter source="get-property('MESSAGE_FORMAT')" regex="soap1[1-2]">
<then>
<property name="SOAP_FAULT_CODE" value="Server"/>
<makefault>
<code expression="$ctx:SOAP_FAULT_CODE"/>
<reason expression="$ctx:ERROR_MESSAGE"/>
</makefault>
</then>
<else>
<payloadFactory>
<format>
<CountryDetailsError>
<code>$1</code>
<type>Error Encountered</type>
<message>An error occurred when trying to get the details of the requested country</message>
</CountryDetailsError>
</format>
<args>
<arg expression="$ctx:ERROR_CODE"/>
</args>
</payloadFactory>
<property name="messageType" value="application/json" scope="axis2"/>
</else>
</filter>
After saving the file you need to copy this file into the location wso2am-2.1.0/repository/deployment/server/synapse-configs/default/sequences/ if you are creating this API in the tenant mode then you need to copy this sequence to the location
wso2am-2.1.0/repository/tenants/{tenant_id}/synapse-configs/default/sequences
Further more you can handle custom error codes and provide different messages for them as well. The error codes returned can be found here.
Hi Shenavi, thanks for the useful blow, but can you please tell me how to handle a situation in which I want to expose two APIs by WSO2 API Manager to the external customers - one as REST (JSON) and the other as SOAP (XML) based and in case of REST based, I need that all types of errors including the invalid input being entered, authorization issue, API blocked, subscription throttling issue to be send as a JSON response and in case of SOAP, to be sent as SOAP based. Please let me know on this.
ReplyDeleteIn summary what you need is for your JSON based API to return a JSON formatted fault message and your SOAP based API to send an XML based message? In that case you can add the following property to your fault sequence which will simply do the transformation for you. Set the messageType property to application/json or application/xml accordingly
DeleteRefer https://docs.wso2.com/display/ESB481/Generic+Properties#GenericProperties-messageType