continueOnError="true" + RaiseFault (in shared flow): an anti pattern?

guycrets
Participant IV

Using the JSONThreatProtection policy in a shared flow with continueOnError="true".

Reason for doing so is that I can have error handling with RaiseFault within the shared flow.

But hardly any information is available about the reason why the policy, JSONThreatProtection in this case, failed.

Is continueOnError + RaiseFault in a shared flow bad practice, an anti-pattern"?

How to create encapsulated shared flows that do not require fault handling at proxy level?

0 3 533
3 REPLIES 3

deniska
Participant V

The reasons you can see that caused failure described here: https://docs.apigee.com/api-platform/troubleshoot/policies/runtime/jsonthreatprotection-errors#excee...

Why usage of fault blocks on relevant flow (that is transferred "up" from shared-flow) is not good practice in your opinion?

Thanks for your feedback. Had also found this interesting article regarding JSONThreatProtection erros.

But question is more generic: error handling in shared flows. Main driver for handling errors in the shared flow itself is to avoid that proxy developers need to have knowledge - and do error handling - of underlying and nested shared flows. Striving for "encapsulation".

Hi @guycrets ,

I've created a shared flow to handle errors for all my proxies and I've placed that in the DefaultFaultRule for each proxy. For example:

    <DefaultFaultRule name="ProxyDefaultFaultRule">
        <Step>
            <Name>FC-ProxyErrorHandling</Name>
        </Step>
        <AlwaysEnforce>true</AlwaysEnforce>
    </DefaultFaultRule>
    <FaultRules/>

Regarding, continue on error for policies and then Raise Fault, I don't see that as an anti-pattern. However, you will need to check for errors after the policy executes, RaiseFault, then correlate the RaiseFault in your shared error handling flow. You can do this by the name of the RaiseFault policy.

If I imagine your solution correctly, you have a "security" shared flow that does JSONThreatProtection with continueOnError="true" then checks for an error and then uses a RaiseFault.

Given that, in your common "error handling" shared flow, you would need to identify that error and differentiate from other RaiseFaults, by looking at the RaiseFault error codes (e.g. raisefault.RF-NotFound.failed).

For example, this fragment from a JavaScript policy in my SF ProxyErrorHandling.

var faultName = context.getVariable ("fault.name");
var faultString = context.getVariable ("error.message");

switch(faultName) {
    ...
    case "SpikeArrestViolation" :
        statusCode = "429";
        reasonPhrase = "Too Many Requests";
        code = "429.001";
        description = "Rate limit exceeded";
        break;
    
    case "RaiseFault" :
        if ( 
            (context.getVariable("raisefault.RF-VerbPathNotFound.failed") === true) || 
            (context.getVariable("raisefault.RF-NotFound.failed") === true )
        ) {
            var verb = context.getVariable("request.verb");
            var uri = context.getVariable("proxy.pathsuffix");
            statusCode = "404";
            reasonPhrase = "Not Found";
            code = "404.001";
            description = "No resource for " + verb + " " + uri;
        } else if ( context.getVariable("raisefault.RF-Invalid.failed") === true ) {
            statusCode = "400";
            reasonPhrase = "Bad Request - Schema Validation Failed";
            code = "400.001";
            description = context.getVariable('message.content');
        } else {
            statusCode = context.getVariable("error.status.code");
            reasonPhrase = context.getVariable("error.reason.phrase");
            code = "400.000";
            description = "Uncaught raise fault occurred.";
        }
        break;
    ...

Hope that helps