Executing a policy by default during proxy execution

Not applicable

I want to always execute a policy after every failure in the proxy execution.The result of that policy should be sent to client

So,I tried putting in the Default Fault Rule but when there is failure happening in the <FaultRules>,this is not executed evenif AlwaysEnforce is true.This is expected.

I cannot put this policy in PostClient flow since I want this to be executed before the output goes to client.

Is there anyway to do this?

Solved Solved
1 13 201
1 ACCEPTED SOLUTION

@RK4 I've used DefaultFaultRule in the Proxy with Always set to true as my last policy to assign a "standard error message" using AssignMessage. I catch the Faults in FaultRules and do an intermediate AssignMessage to set headers which are then used in the final DefaultFaultRule AssignMessage.

Here's a fragment:

<ProxyEndpoint name="default">
    <Description/>
    <DefaultFaultRule name="DefaultFaultRule">
        <Step>
            <FaultRules/>
            <Name>AM-Default-Proxy-Fault</Name>
        </Step>
        <AlwaysEnforce>true</AlwaysEnforce>
    </DefaultFaultRule>
    <FaultRules>
        <FaultRule name="no-apikey">
            <Condition>fault.name = "FailedToResolveAPIKey" or fault.name = "InvalidApiKey"</Condition>
            <Step>
                <FaultRules/>
                <Name>Assign-Message-No-Apikey</Name>
            </Step>
        </FaultRule>
        <FaultRule name="raise-fault">
            <Condition>fault.name = "RaiseFault"</Condition>
            <Step>
                <FaultRules/>
                <Name>Assign-Message-Raise-Fault-1</Name>
            </Step>
        </FaultRule>
        <FaultRule name="raise-fault">
            <Condition>fault.name = "RaiseFault"</Condition>
            <Step>
                <FaultRules/>
                <Name>Assign-Message-Raise-Fault-2</Name>
            </Step>
        </FaultRule>
    </FaultRules>

In the various FaultRule AssignMessage policy, I Add header X-trace to show what policies have been executed.

What I discovered is that the DefaultFaultRule in the Proxy fires all the time, even if the DefaultFaultRule in the Target fires. Also note that I'm catching multiple RaiseFault conditions, but the only one that gets fired is Raise-Fault-2, shows order of execution

This accomplished what I wanted to do, use AssignMessage to standardize all faults.

View solution in original post

13 REPLIES 13

Not applicable

Hi @RK4, instead of using DefaultFaultRule, can you try executing it as a FaultRule? In the past, I've noticed that if another FaultRule executes, other rules won't be executed in cascade.

@Diego Zuluaga

You mean to say like the following..?

<FaultRules>

<FaultRule name="FaultRules">

Other error handling policies..

</FaultRule>

<FaultRule name="NewFaultRule">

Policy I want to execute always

</FaultRule>

</FaultRules>

@Diego ZuluagaThe above is not working.

Below is how its getting executed.

1) <FaultRule name="NewFaultRule">

Policy I want to execute always

</FaultRule>

2)Since the above is just a transformation policy and does not throw any error,the policies in the <DefaultFaultRule> gets executed.

So,this does not match my scenario.Mine is after throwing error,I want to execute a policy before sending to client.

I think you need to include not a special rule, but a policy, in every FaultRule. For example,

   <FaultRule name="unknown-fault">
      <!--
        This fault catches all uncaught faults.
        see http://docs.apigee.com/api-services/content/fault-handling


        If multiple fault rules have a condition that evaluates to true,
        then the last of those fault rules executes.
      -->
      <Condition>fault.name != "RaiseFault"</Condition>
      <Step>
        <Name>AM-UnknownFault</Name>
      </Step>
      <Step>
        <Name>XMLToJSON-Response</Name>
        <Condition>request.header.accept =| "application/json"</Condition>
      </Step>
    </FaultRule>


    <FaultRule name='hash-fault-1'>
      <Step>
        <Name>AM-HashErrorResponse</Name>
      </Step>
      <Step>
        <Name>XMLToJSON-Response</Name>
        <Condition>request.header.accept =| "application/json"</Condition>
      </Step>
      <Condition>hash_error != null AND hash_error != ""</Condition>
    </FaultRule>

Notice that I have XMLToJSON-Response occurring in both fault rules (with a condition on that particular policy).

This means the XMLtoJSON is always occurring, regardless of the FaultRule that applies.

The key thing to realize is that a FaultRule implies a sequence of policies, each of which may have a condition.

As far as I know there is no way to say "Run this policy regardless of which FaultRule has been applied".

@Dino

Thanks for responding.

Even I tried the above structure but it still didnt work.

In this structure,

<FaultRule name="FaultRules1"> 
  <Step> 
    <Name>RaiseFault_InvalidTest</Name>
  </Step> 
  <Step>
    <Name>JSON-to-XML-1</Name>
    <Condition>request.header.Content-Type == "application/xml"</Condition> 
  </Step>
  <Condition>request.header.h1 != "test"</Condition> 
</FaultRule>

Once it finds that RaiseFault_InvalidTest throws Fault,it comes out of this FaultRule.

So,second step which contains JSON-to-XML-1 not executed.

yes - I think you do not need to use RaiseFault within a FaultRule. Please use AssignMessage in a FaultRule. The system is already in Fault status. You do not need to RAISE a fault when you are processing faults.

If you swap out the RaiseFault for an equivalent AssignMessage, I Think your JSON-to-XML policy will execute as desired.

That's also correct @Dino. There's no need to raise a fault within a faultrule step. Otherwise, according to what I tested and the documentation, processing will stop immediately.

The policies execute in the order defined. For example, you can use the Message Logging policy, the Extract Variables policy, the Assign Message policy, or any other policy in the fault rule. Note that processing of the fault rule stops immediately if either of these situations occur:
  • Any policy in the fault rule causes an error
  • Any of the policies in the fault rule is of type Raise Fault

> In the past, I've noticed that if another FaultRule executes, other rules won't be executed in cascade.

Diego, I think what you are reporting is the documented, expected behavior. from the documentation:

> When a fault rule's condition evaluates to true, the policies specified in the rule execute. If multiple fault rules have a condition that evaluates to true, then the last of those fault rules executes. This is different behavior from Route Rules and Flow conditions, which execute the first of the set for which a condition evaluates to true.

Not applicable

Someone please help on this solution.

@RK4 I've used DefaultFaultRule in the Proxy with Always set to true as my last policy to assign a "standard error message" using AssignMessage. I catch the Faults in FaultRules and do an intermediate AssignMessage to set headers which are then used in the final DefaultFaultRule AssignMessage.

Here's a fragment:

<ProxyEndpoint name="default">
    <Description/>
    <DefaultFaultRule name="DefaultFaultRule">
        <Step>
            <FaultRules/>
            <Name>AM-Default-Proxy-Fault</Name>
        </Step>
        <AlwaysEnforce>true</AlwaysEnforce>
    </DefaultFaultRule>
    <FaultRules>
        <FaultRule name="no-apikey">
            <Condition>fault.name = "FailedToResolveAPIKey" or fault.name = "InvalidApiKey"</Condition>
            <Step>
                <FaultRules/>
                <Name>Assign-Message-No-Apikey</Name>
            </Step>
        </FaultRule>
        <FaultRule name="raise-fault">
            <Condition>fault.name = "RaiseFault"</Condition>
            <Step>
                <FaultRules/>
                <Name>Assign-Message-Raise-Fault-1</Name>
            </Step>
        </FaultRule>
        <FaultRule name="raise-fault">
            <Condition>fault.name = "RaiseFault"</Condition>
            <Step>
                <FaultRules/>
                <Name>Assign-Message-Raise-Fault-2</Name>
            </Step>
        </FaultRule>
    </FaultRules>

In the various FaultRule AssignMessage policy, I Add header X-trace to show what policies have been executed.

What I discovered is that the DefaultFaultRule in the Proxy fires all the time, even if the DefaultFaultRule in the Target fires. Also note that I'm catching multiple RaiseFault conditions, but the only one that gets fired is Raise-Fault-2, shows order of execution

This accomplished what I wanted to do, use AssignMessage to standardize all faults.

Awesome! That worked for me 🙂

Thankyou @Kurt Kanaskie

I have changed Raise Fault to Assign message policy.In Default FaultRule created a transformation policy with Source as Error and Output as Error.It worked !

So glad to hear it!!

Thank you @Dino. Because of experts in this forum, I am able to enjoy my learning... Happy to be here...