apigee

Apigee errorcode: steps.servicecallout.ExecutionFailed - Reason: ResponseCode 400 is treated as error


The Problem

The Apigee proxy is transforming the true API response of (Status Code 400 with empty JSON) to Status Code 500 and a canned Apigee error response.

API Response Without Apigee

Status Code 400: Bad Request
{}

API Response Through Apigee

Status Code 500: Internal Server Error

{
    "fault": {
        "faultstring": "Execution of ServiceCallout serverPermitGetCallout failed. Reason: ResponseCode 400 is treated as error",
        "detail": {
            "errorcode": "steps.servicecallout.ExecutionFailed"
        }
    }
} 

The Question

Apigee Docs doesn't seem to help.

I want Apigee to skip interception and message injection (transformation), and let the original result and status code pass through.

I've tried a combination of RaiseFault scenarios, but got nowhere. I get the feeling those are intended for Request.

What am I missing here? Surely this is a simple thing, but I cannot seem to figure out what I need to setup.

Proxy Endpoint

        <Flow name="getServerPermit">
            <Condition>(proxy.pathsuffix MatchesPath "/abc**") and (request.verb = "GET")</Condition>
            <Description/>
            <Request>
                <Step>
                    <Name>serverPermitGetCallout</Name>
                </Step>

            </Request>
            <Response>
                <Step>
                    <Name>serverPermitAssign</Name>
                </Step>
            </Response>
        </Flow>

Policy Callout

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout async="false" continueOnError="false" enabled="true" name="abcServerPermitGetCallout">
    <DisplayName>serverPermitGetCallout</DisplayName>
    <Properties/>
    <Request clearPayload="true" variable="serverPermitGetCalloutRequest">
        <Set>
            <Verb>GET</Verb>
        </Set>
        <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    </Request>
    <Response>serverPermitGetCalloutResponse</Response>
    <HTTPTargetConnection>
        <Properties/>
        <URL>https://{abc_endpoint}/api/consume/auth?{request.querystring}</URL>
    </HTTPTargetConnection>
</ServiceCallout>

Policy Assign

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="abcServerPermitAssign">
    <DisplayName>serverPermitAssign</DisplayName>
    <Properties/>
    <AssignTo createNew="true" transport="http" type="response"/>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <Set>
        <Payload contentType="application/json" variablePrefix="%" variableSuffix="#">
            %serverPermitGetCalloutResponse.content#
        </Payload>
    </Set>
</AssignMessage>

Solution

  • By default, any non 2xx response from a service callout policy is treated as an error as you see from the response. There are two ways to override this behavior.

    1. Set the continueOnError flag in your service callout policy to true. This would ignore all errors arising out of the policy and continues with the flow.
    2. Use the Properties tag under HTTPTargetConnection in your service callout policy to set the success.codes property to treat 400 status code as success response.

    References: