Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
santhosh_kumarv
Active Contributor

Introduction


An API proxy could encounter many error conditions when servicing an request. These error occurs when a policy could not do what it was designed to do. In this blog we will see how to use FaultRules and DefaultFaultRule to implement a custom fault handling branch for such errors.

By default SAP API Management returns an Error code (HTTP Status) and fault message to the client application upon error. The Error and HTTP status code are documented in help.sap document for every policy. Below is an example for Verify API Key policy.



The default error message may sound mysterious at times to the consumers. So it's a good practice to customize the error message and enrich it with information to resolve error and also return custom Header or HTTP Status code if required.  Some use cases may also require execution of sequence of policy upon error {Eg. Log error and Return Custom Message}

The custom HTTP code and/or custom message can be raised using Raise Fault Policy however a common error handling pattern can only be implemented using FaultRules and DefaultFaultRule.

FaultRules and DefaultFaultRule


When an API proxy encounters error it exits the normal processing pipeline and enters into error state. In error state the API Proxy checks for FaultRules and DefaultFaultRule in the same order for execution.

  • FaultRules - Contains the logic to trigger custom error messages (and other policies) based on specific conditions

  • DefaultFaultRule - Contains the logic to trigger custom error messages (and other policies) when no FaultRule is executed or AlwaysEnforce element is set to true.


Important Note:

  • An API Proxy enters error state only when continueOnError attribute is set to false on policy or when Raise Fault Policy is executed.

  • FaultRule is evaluated bottom to top in Proxy Endpoint and top to bottom in Target Endpoint.

  • Only the first matching FaultRule is executed.


Implementation


Lets take below simple scenario to exercise Fault Handling.


The proxy has two policy

  • Verify API key policy (checkAPIKey) - Check if the request has a valid API Key in Header.

  • Basic Authentication policy (decodeBasicCreds) - Decodes and read user name and password from Authorization Header


Without any Fault Handling in-place the API returns below error.

Case 1 : No API Key


Case 2 : Invalid API Key


Case 3 : Valid API Key without Basic Authorization


Now lets move on to include Fault Handling into the Proxy flow.

Step - 1 :

Create an Assign Message Policy to generate response for "FailedToResolveAPIKey" error code [Case-1].


<!-- This policy can be used to create or modify the standard HTTP request and response messages -->
<AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
<Set>
<Payload contentType="application/json" variablePrefix="@" variableSuffix="#">
{
"Cause":"Request sent without API Key",
"Resolution" : "Add APIKey Header parameter with valid API Key"
}
</Payload>
<StatusCode>911</StatusCode>
<ReasonPhrase>Request Missing API Key</ReasonPhrase>
</Set>
<Add>
<Headers>
<Header name="APIKey">No API key</Header>
</Headers>
</Add>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

Step - 2 :

With "NoAPIKeyError" Policy selected in Flow Editor, Click Delete. This would remove the Policy from the Flow sequence(only), however it will remain in the Proxy Resource (Created Policies) to be used in Fault Rule [Step - 5].



Step - 3 :

Repeat step 1 & 2 to create Assign Message Policy for other two error types and default error. Below is the code Snippet.

InvalidAPIKeyError
<!-- This policy can be used to create or modify the standard HTTP request and response messages -->
<AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
<Set>
<Payload contentType="application/json" variablePrefix="@" variableSuffix="#">
{
"Cause":"Request contain invlaid API Key",
"Resolution" : "Inser valid APIKey in Header"
}
</Payload>
<StatusCode>911</StatusCode>
<ReasonPhrase>Invalid API Key</ReasonPhrase>
</Set>
<Add>
<Headers>
<Header name="APIKey">Invalid API key</Header>
</Headers>
</Add>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

BasicAuthMissing
<!-- This policy can be used to create or modify the standard HTTP request and response messages -->
<AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
<Set>
<Payload contentType="application/json" variablePrefix="@" variableSuffix="#">
{
"Cause":"Authorization Header Missing",
"Resolution" : "Add Basic Authentication to Request Message"
}
</Payload>
<StatusCode>911</StatusCode>
<ReasonPhrase>Missing Basic Authorization</ReasonPhrase>
</Set>
<Add>
<Headers>
<Header name="BasicAuth">Missing</Header>
</Headers>
</Add>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

defaultFaultHandler
<!-- This policy can be used to create or modify the standard HTTP request and response messages -->
<AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
<Set>
<Payload contentType="application/json" variablePrefix="@" variableSuffix="#">
{
"Cause":"SERVICE UNAVAILABLE.",
"Resolution" : "CONTACT SUPPORT: helpdesk@abc.com."
}
</Payload>
<StatusCode>911</StatusCode>
<ReasonPhrase>SERVICE UNAVAILABLE</ReasonPhrase>
</Set>
<Add>
<Headers>
<Header name="DefaultFaultHeader">{fault.name}</Header>
</Headers>
</Add>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

After this steps the Policy Flow look the same, however 4 new Assign Message Policy are available to be used in the Flow.


Step - 4 :

Return to Proxy Overview Main Screen and hit Export from Top right corner.



Unzip the file. Read API Proxy Structure help documentation for more information about the file structure.



Step - 5 :

Open APIProxyEndPoint\default.xml in a text editor of your choice.



Lets start Adding Fault Rule to the Proxy Flow using Configuration XML {As it's not supported in UI yet}. Insert below code replacing the existing <faultRules/> element.
<faultRules>
<faultRule>
<name>NoAPIKeyError</name>
<condition>(fault.name = "FailedToResolveAPIKey")</condition>
<steps>
<step>
<policy_name>NoAPIKeyError</policy_name>
<condition> </condition>
<sequence>1</sequence>
</step>
</steps>
</faultRule>
<faultRule>
<name>InvalidAPIKeyError</name>
<condition>(fault.name = "InvalidApiKey")</condition>
<steps>
<step>
<policy_name>InvalidAPIKeyError</policy_name>
<condition> </condition>
<sequence>1</sequence>
</step>
</steps>
</faultRule>
<faultRule>
<name>BasicAuthMissing</name>
<condition>(BasicAuthentication.decodeBasicCreds.failed = true)</condition>
<steps>
<step>
<policy_name>BasicAuthMissing</policy_name>
<condition> </condition>
<sequence>1</sequence>
</step>
</steps>
</faultRule>
</faultRules>

Note :

  • faultRule/steps/step can be repeated to chain multiple policies.

  • faultRule/condition can use either of [prefix].[policy_name].failed or fault.[error_name] Fault Variables.


Step - 6 :

Open APITargetEndPoint\default.xml in a text editor of your choice.



Insert <defaultFaultRule> code between <faultRules/> and <preFlow>.
<defaultFaultRule>
<name>defaultfaultRule</name>
<alwaysEnforce>true</alwaysEnforce>
<steps>
<step>
<policy_name>defaultFaultHandler</policy_name>
<condition> </condition>
<sequence>1</sequence>
</step>
</steps>
</defaultFaultRule>

Step - 7 :

Zip the API Proxy Folder and return to Develop API main screen. Import the ZIP file by choosing Import API.





The Proxy is now updated with Fault handling. Lets test!

Test Result


No API Key in Header


Invalid API Key in Header


Valid API key but no Basic credentials


Valid API key but Incorrect Basic credentials : Error returned by Target service and defaultFaultRule executed.
11 Comments
Labels in this area