Skip to Content
Technical Articles

SAP API Management – Handling Faults using FaultRules and DefaultFaultRule

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.

9 Comments
You must be Logged on to comment or reply to a post.
  • Hi Santhosh –  Well articulated.

    Using this approach we can ensure API Proxy’s error messages can be returned in a uniform format to the calling plication.

    SAP API Management should provide this feature as part of the API Proxy UI Screen otherwise it will be cumbersome to use this feature.

    Anyway thanks for sharing this useful insight.

    Cheers

    Rajesh Pasupula

     

     

     

     

  • Very nice article Santhosh Kumar Vellingiri!

    One question, do you know if SAP API Management accepts the creation of N Target endpoints as it is possible in Apigee? I am not able to see that option in the UI designer so I understand that needs to happen doing export and import of the API?

    Many thanks for your help,

    C.

  • Hi Santhosh

    What a excellent blog!I was just exploring Fault management in API M and your blog was a eye opener. Of course, makes you wonder why this is not available in the standard Policy Management UI for modelling.

    If I may ask – how did you figure this out? Is there some standard document from SAP on this? Or do you need to know Apigee to get to this level of expertise?

    Is there a easy way to save this as templates to apply to all your APIs or this needs to be done for each API.

    Once again, excellent blog.

     

    Regards

    Bhavesh

    • Hi Bhavesh,

       

      Thanks for your comment. I’m glad you found it informative.

      Yes not having it in UI for modelling make it cumbersome. May be it’s in SAP road-map and that could also be the reason why the details are not documented in SAP help portal.

      My knowledge in applying this was purely from Apigee basics and Trial and Error method.

      Policy templates is not helpful either for fault-rule configuration. It so far works only for pre, post and conditional flows. However Policy templates at least copies the policies to the proxy artifact.

       

      Thanks,

      Santhosh