Many error conditions can arise while API proxies are servicing requests from apps. For example, API proxies may encounter network issues when communicating with backend services, apps may present expired credentials, request messages may be incorrectly formatted, and so on. In many cases, you will need to handle such errors in a customized fashion. This topic shows you how to set up custom fault handling using the controls provided by API Services.

When an API proxy encounters an error, the default behavior is to 'exit' from the normal processing pipeline and to enter an 'error Flow'. The error Flow bypasses any remaining processing Steps, and therefore any Policies, in an API proxy. The result can be that raw error message or codes are returned to the requesting app. You probably want to modify this behavior to improve both usability and security.

API Services enables you to customize exception handling by defining FaultRules. FaultRules can be attached to ProxyEndpoints, TargetEndpoints, and RouteRules.

A FaultRule is an XML configuration element that specifies two elements:

  • A Condition that classifies a fault based on the pre-defined category, subcategory, or name of the fault
  • One or more Policies that define the behavior of the FaultRule

The basic structure of a FaultRule is shown below:

<FaultRule>
  <Step>
    <Name>{policy_name}</Name>
  </Step>
  <Condition>{(conditional statement)}</Condition>
</FaultRule>

When a FaultRule's condition evaluates to true, then the Policy named in the FaultRule will execute, and the policy in the last FaultRule that matches the same conditions will also execute.  This is different behavior from Route Rules and Flow conditions which stop once a condition is met. In those cases, even if environment conditions match subsequent Route Rules and Flow conditions, those Route Rules and Flows will be ignored.

You can learn how to configure conditions by referring to the topic Flow variables and conditions.

Attaching FaultRules

You can attach FaultRules to the following entities in an API proxy configuration:

  • ProxyEndpoint: Enables fault handling for all errors that occur in the ProxyEndpoint request and response flows.
  • TargetEndpoint: Enables fault handling for all errors that occur in the TargetEndpoint request and response flows.
  • RouteRule: Enables target routing based on error conditions.

To configure fault handling, define a FaultRule, and then attach one or more Policies to the FaultRule as processing Steps (in the same way that you apply policies to a Flow as processing Steps). The difference is that the FaultRule executes only when an error condition is encountered.

To add a FaultRule you need to directly edit the XML configuration in the Code pane of the Develop view for an API proxy.

Handling errors during flow processing

FaultRules are most commonly used to customize the handling of errors that occur while an API proxy is executing policies. For example, you may need to send a custom error message when a developer app exceeds a Quota, or you may need to perform a ServiceCallout if an entry cannot be found in the Cache.

Each Policy type defines a set of 'error codes'. You can find the error codes for each Policy type in the Policy reference, starting with the Policy reference overview.

All Policy errors have the same format. The format of Policy errors is shown in the example below:

{
  "code" : " {error.code} ",
  "message" : " {Error message} ",
  "contexts" : [ ]
}

For example, when a developer app presents and invalid consumer key, the VerifyApiKey policy type returns the following error code:

{
  "code" : " InvalidApiKey ",
  "message" : "The consumer key presented by the app is invalid.",
  "contexts" : [ ]
}

You can use this error code to specify the type of processing that the API proxy should perform when a developer app presents invalid consumer key. For example, to customize a response for this error, you can include this error code in a Condition using the fault.name variable.

<FaultRule>
  <Step>
    <Name>fault_invalidkey</Name>
  </Step>
  <Condition>(fault.name = "InvalidApiKey")</Condition>
</FaultRule>

The FaultRule above will execute if an error with the name 'InvalidApiKey' is thrown by the VerifyApiKey policy.

Once you have configured the FaultRule, then you attach this FaultRule to the ProxyEndpoint as follows:

<ProxyEndpoint name="default">
  <FaultRules>
    <FaultRule name="invalid_key_rule">
      <Step>
	    <!-- The name of the policy that will execute if the Condition evaluates to true. -->
        <Name>fault_invalidkey</Name>
      </Step>
        <!-- The conditional statement that Apigee Edge uses to evaluate for error states. -->
      <Condition>fault.name = "InvalidApiKey"</Condition>
    </FaultRule>
  </FaultRules>
</ProxyEndpoint>

InvalidApiKey is a fault name. Every policy type supports a pre-defined set of fault names and fault codes. The properties in the fault response that are associated with each fault are errorCode and error. Consult the policy reference for a list error codes returned by each policy type.

Now that you have configured a FaultRule on the ProxyEndpoint, you need to add a policy of type RaiseFault. The RaiseFault policy will define the behavior of your API proxy when the fault condition occurs.

The example below demonstrates a typical RaiseFault policy configuration. RaiseFault enables you to configure a FaultResponse element with Payload, HTTP status code and reason phrase elements. The policy will generate a standard HTTP response using these elements.

<RaiseFault name="fault_invalidkey">
  <FaultResponse>
    <Set>
      <Payload contentType="text/plain">Contact support at support@mycompany.com.</Payload>
      <StatusCode>401</StatusCode>
      <ReasonPhrase>Unauthorized</ReasonPhrase>
    </Set>
  </FaultResponse>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>

When you deploy the configuration above, the API proxy will execute the RaiseFault policy called fault_invalidkey whenever an app presents and invalid API key.

You can find complete documentation of the options exposed by the RaiseFault policy in the topic Raise Fault policy.

As you can see in the configuration above, a ProxyEndpoint or TargetEndpoint supports multiple FaultRules. You can attach as many FaultRules to an Endpoint as you want. Keep in mind that only the first FaultRule whose Condition evaluates to true will execute. The exception to this rule is the DefaultFaultRule, which can be configured to execute even though another FaultRule has already fired.

Configuring default fault rules

The DefaultFaultRule acts an exception handler for any error that is not explicitly handled by a FaultRule. If no FaultRules are configured in an API proxy, then the DefaultFaultRule will handle all faults that occur. Default fault handling can be enabled by configuring DefaultFaultRule as a child element of a ProxyEndpoint or a TargetEndpoint.

The TargetEndpoint configuration below is configured with a DefaultFaultRule. The FaultRule indicates that when an error condition is encountered during message processing, a policy called ReturnError executes.

<TargetEndpoint name="default">
    <DefaultFaultRule name="fault-rule">
      <Step>
        <Name>ReturnError</Name>
      </Step>
    </DefaultFaultRule>

  <HTTPTargetConnection>
    <URL>http://weather.yahooapis.com</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

DefaultFaultRule is typically used to return a generic error message for any unexpected error. For example, you might configure the DefaultFaultRule to return a message that contains support contact information. This serves the dual purpose of providing developer-friendly information while also obfuscating backend URLs or other information that might be used to compromise the system.

For example:

<ProxyEndpoint name="MyProxyEndpoint">
  <DefaultFaultRule name="GenericFaultHandler">
  </DefaultFaultRule>
  ....
</ProxyEndpoint>

You customize the behavior of the DefaultFaultRule by attaching one or more Policies as processing Steps.

<DefaultFaultRule name="GenericFaultHandler">
  <Step><Name>ReturnGenericFaultMessage</Name></Step>
  <AlwaysEnforce>true</AlwaysEnforce>
</DefaultFaultRule>

The AlwaysEnforce element is provided to enable DefaultFaultRules to execute even when other FaultRules in an API proxy Flow have executed. When the AlwaysEnforce element is set to true, the FaultRule is always enforced, even if fault handling has executed in a previous processing phase.

Set the flag AlwaysEnforce to true on DefaultFaultRule. This enables the DefaultFaultRule to process any faults captured by more specific FaultRules. In this case, you can customize the error response (by adding an HTTP header, for example) on the ProxyEndpoint.

An example of a simple Policy that you might use with a DefaultFaultRule is shown below. The policy is of type AssignMessage, and generates a simple text response for any predefined error condition:

<AssignMessage name="ReturnError">
  <Set>
    <Payload type="text/plain">SERVICE UNAVAILABLE. PLEASE CONTACT SUPPORT: support@company.com.</Payload>
  </Set>
</AssignMessage>

Custom handling of HTTP error codes

The configuration shown in the previous section works for application-level errors. To return custom responses for transport-level (that is, HTTP) errors, you must configure a Property on the TargetEndpoint that enables the TargetEndpoint to process HTTP response codes.

By default, HTTP response codes in the 2xx-3xx range are treated as 'success'. HTTP response codes 4xx-5xx are treated as 'failure'. Any response from the backend service with an HTTP response code 400-500 automatically invokes the ErrorFlow. The ErrorFlow automatically returns an error message directly to the requesting client.

To create custom responses to HTTP error codes, you need to override this default behavior. In some cases you might need to return custom errors for HTTP codes 400 and 500. For example, you may need to ensure that all backend service URLs are obfuscated from requesting clients.

To do so, you must first configure the TargetEndpoint to treat HTTP response codes 4xx and 5xx as success codes. By treating those codes as success codes, the TargetEndpoint takes over processing of the response message (rather than pushing the response message into the default ErrorFlow). This enables you to define FaultRules on HTTP error codes that invoke specific policies.

To treat HTTP error codes as success, set the success.codes property on the TargetEndpoint in your API proxy.

<TargetEndpoint name="default">
  <HTTPTargetConnection>
    <Properties>
	  <Property name="success.codes">4XX, 500</Property>
    </Properties>
    <URL>http://weather.yahooapis.com</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

You can then use HTTP response codes 400-499 and 500 to define conditional policy execution that returns a customized response message to the requesting app.

For example, apply the following configuration to a ProxyEndpoint or TargetEndpoint response Flow.

<Response>
  <Step>
    <Condition>(response.status.code = 400) or (response.status.code = 500)</Condition>
    <Name>ReturnError</Name>
  </Step>
</Response>

The Flow configuration above causes the AssignMessage policy called ReturnError to generate a response message whenever the TargetEndpoint encounters an HTTP response code of 400 or 500.

FaultRule processing

Any number of FaultRules can be defined on ProxyEndpoints and TargetEndpoints. When an error occurs, only the first FaultRule whose condition evaluates to true is enforced.

FaultRules are evaluated in the following order:

Request Path:

  1. Fault in ProxyRequest: FaultRules defined at ProxyEndpoint execute
  2. Fault in Routing: FaultRules defined at ProxyEndpoint execute
  3. Fault in TargetRequest: FaultRules defined at TargetEndpoint execute
  4. Fault in outbound request to target URL: FaultRules defined at TargetEndpoint execute

Response Path:

  1. Fault in TargetResponse: FaultRules defined at TargetEndpoint execute
  2. Fault in ProxyResponse: FaultRules defined at ProxyEndpoint execute
  3. Fault in returning response to ProxyEndpoint: FaultRules defined at ProxyEndpoint execute

Policy attachments in a FaultRule are enforced in the order in which the Steps are attached to the FaultRule.

To enable fault handling for an API proxy, fault handlers must be configured to identify and categorize predefined exception conditions, in turn enabling API Services to execute policies that manage the exception.

Fault taxonomy

API Services organizes faults into the following categories and subcategories.

Category Subcategory Fault Name Description
Messaging Failures that occur during the message flow (not including policy failures)
  Custom faults {fault_name} Any faults explicitly handled by the API proxy using the RaiseFault policy
Response codes InternalServerError, NotFound HTTP error codes 5xx, 4xx 
Routing failures NoRoutesMatched Failure in selecting a named TargetEndpoint for a request
Classification failures NotFound Failures caused by a request URI that does not match any BasePath for any ProxyEndpoint configurations (that is, no API proxies match the URL in the client app's request)
Transport HTTP transport-level errors
  Connectivity ConnectionRefused, ConnectionReset, ConnectionTimeout Failures occur while establishing network or transport-level connections
Request validations ContentLengthMissing, HostHeaderMissing Faults occur during semantics checks on every request
Response validations Faults occur during semantics checks on every response
IO errors SSLHandshakeError, ReadTimeout, ReadError, WriteTimeout, WriteError, ChunkError Read/write errors at client or target endpoints, timeouts, SSL errors, and chunked errors
System Undefined runtime errors
  Memory OutOfMemory, GCOverLimit Memory-related failures
Thread RogueTaskTerminated Failures such as termination of run-away tasks
Step Faults for each Step (Policy) type are defined in the Policy Reference. See Policy reference overview.

An error is always accompanied by a text description of the reason for the failure. When the system raises a fault, a set of attributes are populated to assist in troubleshooting. A fault includes the following information:

  • Reason
  • User-defined custom attributes

Help or comments?

  • Something's not working: See Apigee Support
  • Something's wrong with the docs: Click Send Feedback in the lower right.
    (Incorrect? Unclear? Broken link? Typo?)