I just can't get my head wrapped around how to handle different faults. I need to capture the faults and send back a custom XML response to the clients. I have tried several different ways to do this but have not been able to get the custom response to be sent. I can see in the trace where the check was made but the step was skipped because the condition did not match. In this API i would need to set a couple of different fault rules. One for the schema validation and one if the target server is not available. I'm sure I will need to add more as I go along. Not sure how to set this up, any help would be greatly appreciated.
Below is my proxy endpoint and my target endpoint.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ProxyEndpoint name="default"> <Description/> <FaultRules/> <PreFlow name="PreFlow"> <Request> <Step> <Name>Set-Content-Type</Name> </Step> <Step> <Name>SubscriberInquiry-Validation</Name> </Step> <Step> <Name>SubscriberInquiry_req</Name> </Step> <Step> <Name>Extract-Header-Values</Name> </Step> <Step> <Name>Assign-Header-Values</Name> </Step> </Request> <Response> <Step> <Name>SubscriberInquiry_rep</Name> </Step> </Response> </PreFlow> <PostFlow name="PostFlow"> <Request/> <Response/> </PostFlow> <Flows/> <HTTPProxyConnection> <BasePath>/ejav-eps-subscriberinquiry-service</BasePath> <Properties/> <VirtualHost>default</VirtualHost> </HTTPProxyConnection> <RouteRule name="SubscriberInquiry"> <TargetEndpoint>TargetEndpoint-SubscriberInquiry</TargetEndpoint> </RouteRule> <RouteRule name="default"> <TargetEndpoint>default</TargetEndpoint> </RouteRule> </ProxyEndpoint>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <TargetEndpoint name="TargetEndpoint-SubscriberInquiry"> <Description/> <FaultRules/> <PreFlow name="PreFlow"> <Request/> <Response/> </PreFlow> <PostFlow name="PostFlow"> <Request/> <Response/> </PostFlow> <Flows/> <HTTPTargetConnection> <LoadBalancer> <Server name="ejav-eps-target-inquiry-1"/> <Server name="ejav-eps-target-inquiry-2"/> </LoadBalancer> <Path>/Eps/EPSHttpService</Path> </HTTPTargetConnection> </TargetEndpoint>
<ProxyEndpoint name="default"> <Description/> <FaultRules/> <DefaultFaultRule name="all"> <AlwaysEnforce>true</AlwaysEnforce> <Step> <Name>my-fault-handling-flow</Name> </Step> </DefaultFaultRule>
Now, there are two/three primary ways in which an error occurs in an Apigee proxy
Hope this helps
@rmishra I set up the DefaultFaultRule, which is trapping all of the errors. The issue I have now is I am attempting to transform the fault to XML using JSONToXML, setting the content-type back to application/xml then doing a XML transformation to send back a XML formatted response to the client. I don't then the JSONToXML is working which causes a error when I try to reset the content-type - Unexpected character ({) at position 0, therefore the XSL transformation never occurs.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ProxyEndpoint name="default"> <Description/> <FaultRules/> <DefaultFaultRule name="all"> <AlwaysEnforce>true</AlwaysEnforce> <Step> <Name>ConvertFault</Name> </Step> <Step> <Name>Set-Content-Type</Name> </Step> <Step> <Name>SystemError</Name> </Step> </DefaultFaultRule> <PreFlow name="PreFlow"> <Request> <Step> <Name>Set-Content-Type</Name> </Step> <Step> <Name>SubscriberInquiry-Validation</Name> </Step> <Step> <Name>SubscriberInquiry_req</Name> </Step> <Step> <Name>Extract-Header-Values</Name> </Step> <Step> <Name>Assign-Header-Values</Name> </Step> </Request> <Response> <Step> <Name>SubscriberInquiry_rep</Name> </Step> </Response> </PreFlow> <PostFlow name="PostFlow"> <Request/> <Response/> </PostFlow> <Flows/> <HTTPProxyConnection> <BasePath>/ejav-eps-subscriberinquiry-service</BasePath> <Properties> <Property name="success.codes">4xx,5xx</Property> </Properties> <VirtualHost>default</VirtualHost> </HTTPProxyConnection> <RouteRule name="SubscriberInquiry"> <TargetEndpoint>TargetEndpoint-SubscriberInquiry</TargetEndpoint> </RouteRule> <RouteRule name="default"> <TargetEndpoint>default</TargetEndpoint> </RouteRule> </ProxyEndpoint>
JSONToXML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <JSONToXML async="false" continueOnError="false" enabled="true" name="ConvertFault"> <DisplayName>ConvertFault</DisplayName> <Properties/> <Options> <NullValue>NULL</NullValue> <NamespaceBlockName>#namespaces</NamespaceBlockName> <DefaultNamespaceNodeName>$default</DefaultNamespaceNodeName> <NamespaceSeparator>:</NamespaceSeparator> <TextNodeName>#text</TextNodeName> <AttributeBlockName>#attrs</AttributeBlockName> <AttributePrefix>@</AttributePrefix> <InvalidCharsReplacement>_</InvalidCharsReplacement> <ObjectRootElementName>Root</ObjectRootElementName> <ArrayRootElementName>Array</ArrayRootElementName> <ArrayItemElementName>Item</ArrayItemElementName> </Options> <OutputVariable>response</OutputVariable> <Source>request</Source> </JSONToXML>
Can this process even happen?
@Rick Decker When you say that you are trying to convert a fault to an XML, what kind of Fault are you talking about - An error in the apigee context , A Soap Fault?
If there is an error in the apigee context which you created (request validation failure)/ apigee generated (operational error, bug), the flow would now be short circuited to error handling shared flow.
Now, one of the policies in your shared error flow should be a "Raise Fault" Policy . If you are handling multiple content-types in your request,
<Set> <Payload contentType="application/xml"> <error> <code>{my.error.code}</code> <message>{my.error.message}</message> </error> </Payload> </Set>
Here, my.error.code and my.error.message are the apigee context variables which you may have set to include details about the error. It's perfectly fine to include string literals instead of context variables
@rmishra - Get the raise fault and actually have a it working where I send back a XML formatted response. But I also need to capture the request coming in and append the response to that request and send it back to the client. As far as I can tell there is no way to do that in a raise fault using the set payload. You are manually building XML the XML and have to include a tag for everything. I can capture the request but I need to be able to copy each element with tags. So is there anyway possible to raise a fault and set a XSL transform step so that a complete XML can be built with a request and response. I have not be able find any policy, i.e. Assign Message, Raise fault, etc where you can set that step. It does out clients no good if they receive a error response if they have no idea what the error is for.
@Rick DeckerYou can meet the requirement of correlating the request and response by inserting a "Tracking Id" in the request header, the response (even if it is an error) must carry the same tracking Id header.
BUT if you were absolutely insistent on on inserting the original request into the error structure, in the Proxy Flow (Or Preflow) store the original request into a context variable. Use the context variable and insert it into the Raise Fault XML Template. Apigee should treat the context variable as a string (even if it has XML tags) and just append the string (even though its XML) to your error template.
User | Count |
---|---|
2 | |
2 | |
1 | |
1 | |
1 |