Error Code & Description set in header instead of Body.

Not applicable

I have use case to set the error code and its message as in header variable instead of show the default fault Json in Body. Say example: Api Key policy failed due to invalid Api Key. I do not want to show default fault JSon in Body. Body should be Empty, but error code and its message should be in displayed in header variables. Here, error code 401 as part of header. So, only fault string also show in header.Screen shot shows how the error would be by default. Default fault json should go away.

3498-capture48.png

0 14 1,104
14 REPLIES 14

Hi @Kumaresan Sithambaram

Every policy has defined error codes, you can find them in the policy docs. For VerifyAPIKey policy, the errors are listed here. For your above scenario, the error is InvalidApiKey.

You can use FaultRules to configure a policy to execute when this error occurs. More info here

<FaultRule name="invalid_apikey_rule">
	<Step>
		<Name>error_message_invalid_apikey</Name>
	</Step>
	<Condition>(fault.name = "InvalidApiKey") or (fault.name = "FailedToResolveAPIKey")</Condition>
</FaultRule>

Here - error_message_invalid_apikey is an Assign Message policy where I can set any payload / headers and status code in the response

Hope this helps !

@Sai Saran Vaidyanathan Unfortunately, I supposed not share proxy publicly. Is there any other option. I can create apigee case and share it.do you have access ?

No worries. Please send it to ssvaidyanathan@apigee.com. Or else you can drop it on dropbox and give access to my email id

@Meghdeep Basu, Thanks !! Yes, that change get rid off the error body when use the RaiseFault policy instead of Assign Message. But, I get HTTP status code as 500 - Unauthorized instead of 401 when use Raise Fault whereas Assign Message returns 401 which is correct for Invalid Api Key. Why that difference ?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RaiseFault async="false" continueOnError="false" enabled="true" name="Raise-Fault-SetErrorResponse">
    <DisplayName>Raise Fault-SetErrorResponse</DisplayName>
    <Properties/>
    <FaultResponse>
        <Remove>
            <Payload/>
        </Remove>
        <Set>
            <Headers>
                <Header name="Error-Message">{error.message}</Header>
                <Header name="Error-Code">{error.status.code}</Header>
            </Headers>
            <StatusCode>{error.status.code}</StatusCode>
        </Set>
    </FaultResponse>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>

@Kumaresan Sithambaram

As we all know, whenever the error happens in any policy, the error code is generated. Can you please confirm if this is consistent. Second, please check how we are setting the {error.status.code}. May be this parameter is set to 500.If still issue persist, please allow me to have a look at proxy.

Not applicable

Hello @Kumaresan Sithambaram

Just to add what @Sai Saran Vaidyanathan has said, the content of the policy error_message_invalid_apikey could be something like this, in order to send the error in header and not in body.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RaiseFault async="false" continueOnError="false" enabled="true" name="error_message_invalid_apikey">
<DisplayName>error_message_invalid_apikey</DisplayName>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<FaultResponse>
<Remove>
	<Headers/>
	<Payload/>
</Remove>
<Set>
	<Headers>
		<Header name="Error Code">401</Header>
		<Header name="Fault String">Invalid API Key</Header>
	</Headers>
	<StatusCode>401</StatusCode>
</Set>
</FaultResponse>
</RaiseFault>

Hope this helps !

@Sai Saran Vaidyanathan

and

@Meghdeep Basu

I am able to set the Headers. But, still default body message did not go away. I tried on both Assign Message and Raise Fault Policies. Any idea how should I take off the default fault json body.

This is my fault configuration in preflow 'default' :

    <DefaultFaultRule name="Default-Fault-rule">    
        <Step>
            <Name>Raise-Fault-SetErrorResponse</Name>
        </Step>
        <AlwaysEnforce>true</AlwaysEnforce>
    </DefaultFaultRule>

3499-capture49.png

Can you share your Assign Message policy ?

@Sai Saran Vaidyanathan Thanks !!

Here is Assign Message Policy which I used.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="SetErrorResponse">
    <DisplayName>SetErrorResponse</DisplayName>
    <Properties/>
    <Add>
        <Headers/>
        <QueryParams/>
        <FormParams/>
    </Add>
    <Remove>
        <Headers/>
        <Payload/>
    </Remove>
    <Set>
        <Headers>           
            <Header name="Error-Message">{error.message}</Header>
            <Header name="Error-Code">{error.status.code}</Header>
        </Headers>
        <QueryParams/>
        <FormParams/>      
        <Path/>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>

Hi @Kumaresan Sithambaram

Can you try removing the <Add> section and also in the AssignTo tag, set createNew to true

Let me know if that works.

@Sai Saran Vaidyanathan

I still see the response body with fault json when i removed the <Add> section and also in the AssignTo tag, set createNew to true. Here is the updated Assign Message policy.

And also, I noticed that with this Assign Message policy the Custom Header variables are not in set whereas Raise-Fault policy gets the custom Header variables in the response. But, both policy returns the fault Json body in the response.

Please let me know if you are looking any more information. Thanks !

Assign Message Policy : NOT Sets "Error-Message" and "Error-Code" headers in response. But still response body exists.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="SetErrorResponse">
    <DisplayName>SetErrorResponse</DisplayName>
    <Properties/>
    <Remove>
        <Headers/>
        <Payload/>
    </Remove>
    <Set>
        <Headers>
            <!-- <Header name="Content-Type">text/xml; charset=utf-8</Header> -->
            <Header name="Error-Message">{error.message}</Header>
            <Header name="Error-Code">{error.status.code}</Header>
        </Headers>
        <QueryParams/>
        <FormParams/>
        <!-- <Verb>GET</Verb> -->
        <!-- <Payload contentType="text/xml">{errorResponseXml}</Payload> -->
        <Path/>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="true" transport="http" type="response"/>
</AssignMessage>

Raise Fault Policy : Sets "Error-Message" and "Error-Code" headers in response. But still response body exists.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RaiseFault async="false" continueOnError="false" enabled="true" name="Raise-Fault-SetErrorResponse">
    <DisplayName>Raise Fault-SetErrorResponse</DisplayName>
    <Properties/>
    <FaultResponse>
        <Remove>
            <Headers/>
            <Payload/>
        </Remove>
        <Set>
            <Headers>
                <Header name="Error-Message">{error.message}</Header>
                <Header name="Error-Code">{error.status.code}</Header>
            </Headers>
            <StatusCode>{error.status.code}</StatusCode>
        </Set>
    </FaultResponse>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>

@Kumaresan Sithambaram - Can you share your proxy ? Will take a look and get back

@Kumaresan Sithambaram

Can you please comment out <Headers/> tag under remove and only leave <Payload/> ?

Not applicable

@Kumaresan Sithambaram , As discussed on the support ticket, it appears you have run into a known issue. To workaround, please set error.status.code to another variable prior to running the Raise Fault policy. Example:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <AssignMessage async="false" continueOnError="true" enabled="true" name="SaveStatusCode"> 
<DisplayName>SaveStatusCode</DisplayName> 
<AssignVariable> 
  <Name>errorCodeTest</Name> 
  <Ref>error.status.code</Ref> </AssignVariable> 
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> 
  <AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>