How to dynamically handle error handling with proper condition

Hello, I need help with figuring out when to use certain conditions or what should be the condition that I need to use to handle dynamic routing or requests when it enters the "error state".

@nagashree_b @mdunker @dchiesa1

Solved Solved
1 1 274
1 ACCEPTED SOLUTION

Thanks for your question. I don't understand what you are intending by this kind of thing: 

<Step>
  <Name>JavaScript-FooFinalResponse</Name>
  <Condition>(this is for proxy.pathsuffix == /foo/try, /foo/bar, and /foo/bar/test)</Condition>
</Step>

That's not a valid condition.  Also what is the point of this JavaScript policy?  Why is there a special JS policy and what does it mean "this is FOR proxy.pathsuffix", etc)

Normally when I structure my API proxies I include a set of requests that are "known" and should pass through. GET /foo,   DELETE /bar, etc.   And then anything else is caught by a wildcard match, which gets a 404 response. The way I do this is like so: 

  <Flows>
    <Flow name='t1'>
      <Request> ... </Request>
      <Response> ... </Response>
      <Condition>proxy.pathsuffix MatchesPath "/foo" and request.verb = "GET"</Condition>
    </Flow>

    <Flow name='t2'>
      <Request> ... </Request>
      <Response> ... </Response>
      <Condition>proxy.pathsuffix MatchesPath "/bar" and request.verb = "DELETE"</Condition>
    </Flow>

    <Flow name='unknown request'>
      <!-- no Condition here - it handles all requests not handled by the above -->
      <Request>
        <Step><Name>RF-Unknown-Request</Name></Step>
      </Request>
    </Flow>

  </Flows>

Also I don't understand what you're attempting to do with your FaultRules. Think of FaultRules as "catch" clauses. If a problem occurs during normal proxy execution, the FaultRules may be triggered. This allows you to customize error messages for specific Fault conditions. For example, if there is an expired OAuth Token, Apigee sends back a standard error message. You may want to send something different back in that case. The FaultRule allows you to do that, to override the "default" response (content and status code). For example, supposing you are using APIKeys for credentials (via VerifyAPIKey), there are various error conditions your proxy might encounter: an invalid key; a known key which is not authorized for the current request; a missing key; an expired key....  To override the error messages for these, your FaultRules in the proxy endpoint might look like this: 

  <FaultRules>
    <FaultRule name="invalid-key">
      <Step>
        <Name>AM-InvalidApiKey</Name>
      </Step>
      <Condition>fault.name = "InvalidApiKey" OR fault.name = "InvalidApiKeyForGivenResource"</Condition>
    </FaultRule>

    <FaultRule name="missing-key">
      <Step>
        <Name>AM-MissingKey</Name>
      </Step>
      <Condition>fault.name = "FailedToResolveAPIKey"</Condition>
    </FaultRule>

    <FaultRule name="key-expired">
      <Step>
        <Name>AM-ExpiredKey</Name>
      </Step>
      <Condition>fault.name = "consumer_key_expired"</Condition>
    </FaultRule>

  </FaultRules>

 ...and each of the AM-XXX policies are AssignMessage in which you can override the payload, the status, the headers even.  Each fault condition has a distinct "fault.name".  Quota exceeded is a different fault.name.  Target timeout is a different fault.name.  Message validation might trigger a different fault.name.  You can override the response for any of those fault conditions, with more FaultRules. The most common policy you will include in a FaultRule is AssignMessage. If you are including lots of other policies, it's probably wrong. 

This is explained formally and in more detail in the fault handling documentation

Also if you use use an explicit RaiseFault for the 415 situation, you probably do not need a FaultRule and an AssignMessage for the 415 situation. Use the RaiseFault to set the payload you want, and then you don't need to override it. 

Also I don't know why you use this sequence: 

<Step>
  <Name>XMLToJSON-Foo1Request</Name>
  <Condition>(this is for proxy.pathsuffix == /foo/try)</Condition>
</Step>
<Step>
  <Name>XMLToJSON-Foo2Request</Name>
  <Condition>(this is for proxy.pathsuffix == /foo/bar)</Condition>
</Step>
<Step>
  <Name>XMLToJSON-Foo3Request</Name>
  <Condition>(this is for proxy.pathsuffix == /foo/bar/test)</Condition>
</Step>

The XMLToJSON policy will transform XML to JSON.  It doesn't matter what the inbound XML is, it will always transform it.  You don't need different XMLToJSON policies for each different proxy.pathsuffix.  That would be ... highly unlikely.  Also I don't know why you'd try to transform XML to JSON just in that point. That seems odd.

If, after reading and understanding what I wrote, you are still not clear on how to proceed, I would suggest that you simplify your scenario.  Consider 2 or 3 requests only.  Eliminate everything that is extraneous. Structure your flows and Fault rules for that simple situation.  Run lots of tests and observe what happens when you add or remove FaultRules, or make other small changes. Then, gradually and iteratively add in support for additional pathsuffixes, validation of content-types, the XMLToJSON policy if you need it, and the other things.  Don't try to build the entire skyscraper at once. Get the concepts and the idea straight with Flows and FaultRules, and then proceed.

 

View solution in original post

1 REPLY 1

Thanks for your question. I don't understand what you are intending by this kind of thing: 

<Step>
  <Name>JavaScript-FooFinalResponse</Name>
  <Condition>(this is for proxy.pathsuffix == /foo/try, /foo/bar, and /foo/bar/test)</Condition>
</Step>

That's not a valid condition.  Also what is the point of this JavaScript policy?  Why is there a special JS policy and what does it mean "this is FOR proxy.pathsuffix", etc)

Normally when I structure my API proxies I include a set of requests that are "known" and should pass through. GET /foo,   DELETE /bar, etc.   And then anything else is caught by a wildcard match, which gets a 404 response. The way I do this is like so: 

  <Flows>
    <Flow name='t1'>
      <Request> ... </Request>
      <Response> ... </Response>
      <Condition>proxy.pathsuffix MatchesPath "/foo" and request.verb = "GET"</Condition>
    </Flow>

    <Flow name='t2'>
      <Request> ... </Request>
      <Response> ... </Response>
      <Condition>proxy.pathsuffix MatchesPath "/bar" and request.verb = "DELETE"</Condition>
    </Flow>

    <Flow name='unknown request'>
      <!-- no Condition here - it handles all requests not handled by the above -->
      <Request>
        <Step><Name>RF-Unknown-Request</Name></Step>
      </Request>
    </Flow>

  </Flows>

Also I don't understand what you're attempting to do with your FaultRules. Think of FaultRules as "catch" clauses. If a problem occurs during normal proxy execution, the FaultRules may be triggered. This allows you to customize error messages for specific Fault conditions. For example, if there is an expired OAuth Token, Apigee sends back a standard error message. You may want to send something different back in that case. The FaultRule allows you to do that, to override the "default" response (content and status code). For example, supposing you are using APIKeys for credentials (via VerifyAPIKey), there are various error conditions your proxy might encounter: an invalid key; a known key which is not authorized for the current request; a missing key; an expired key....  To override the error messages for these, your FaultRules in the proxy endpoint might look like this: 

  <FaultRules>
    <FaultRule name="invalid-key">
      <Step>
        <Name>AM-InvalidApiKey</Name>
      </Step>
      <Condition>fault.name = "InvalidApiKey" OR fault.name = "InvalidApiKeyForGivenResource"</Condition>
    </FaultRule>

    <FaultRule name="missing-key">
      <Step>
        <Name>AM-MissingKey</Name>
      </Step>
      <Condition>fault.name = "FailedToResolveAPIKey"</Condition>
    </FaultRule>

    <FaultRule name="key-expired">
      <Step>
        <Name>AM-ExpiredKey</Name>
      </Step>
      <Condition>fault.name = "consumer_key_expired"</Condition>
    </FaultRule>

  </FaultRules>

 ...and each of the AM-XXX policies are AssignMessage in which you can override the payload, the status, the headers even.  Each fault condition has a distinct "fault.name".  Quota exceeded is a different fault.name.  Target timeout is a different fault.name.  Message validation might trigger a different fault.name.  You can override the response for any of those fault conditions, with more FaultRules. The most common policy you will include in a FaultRule is AssignMessage. If you are including lots of other policies, it's probably wrong. 

This is explained formally and in more detail in the fault handling documentation

Also if you use use an explicit RaiseFault for the 415 situation, you probably do not need a FaultRule and an AssignMessage for the 415 situation. Use the RaiseFault to set the payload you want, and then you don't need to override it. 

Also I don't know why you use this sequence: 

<Step>
  <Name>XMLToJSON-Foo1Request</Name>
  <Condition>(this is for proxy.pathsuffix == /foo/try)</Condition>
</Step>
<Step>
  <Name>XMLToJSON-Foo2Request</Name>
  <Condition>(this is for proxy.pathsuffix == /foo/bar)</Condition>
</Step>
<Step>
  <Name>XMLToJSON-Foo3Request</Name>
  <Condition>(this is for proxy.pathsuffix == /foo/bar/test)</Condition>
</Step>

The XMLToJSON policy will transform XML to JSON.  It doesn't matter what the inbound XML is, it will always transform it.  You don't need different XMLToJSON policies for each different proxy.pathsuffix.  That would be ... highly unlikely.  Also I don't know why you'd try to transform XML to JSON just in that point. That seems odd.

If, after reading and understanding what I wrote, you are still not clear on how to proceed, I would suggest that you simplify your scenario.  Consider 2 or 3 requests only.  Eliminate everything that is extraneous. Structure your flows and Fault rules for that simple situation.  Run lots of tests and observe what happens when you add or remove FaultRules, or make other small changes. Then, gradually and iteratively add in support for additional pathsuffixes, validation of content-types, the XMLToJSON policy if you need it, and the other things.  Don't try to build the entire skyscraper at once. Get the concepts and the idea straight with Flows and FaultRules, and then proceed.