反模式:在不当条件下使用 RaiseFault 政策

您正在查看的是 Apigee Edge 文档。
转到 Apigee X 文档
信息

通过 RaiseFault 政策,API 开发者可以启动错误流、在响应正文中设置错误变量,以及设置相应的响应状态代码。您还可以使用 RaiseFault 政策设置与故障相关的流变量,例如 fault.namefault.typefault.category。由于这些变量在用于调试的分析数据和路由器访问日志中可见,因此一定要准确识别故障。

您可以使用 RaiseFault 政策将特定条件视为错误,即使实际错误未出现在另一个政策或 API 代理的后端服务器上。例如,如果您希望代理在只要后端响应正文包含字符串 unavailable 时就向客户端应用发送自定义错误消息,则可以调用 RaiseFault 政策,如以下代码段所示:

<!-- /antipatterns/examples/raise-fault-conditions-1.xml  -->
<TargetEndpoint name="default">
...
  <Response>
    <Step>
      <Name>RF-Service-Unavailable</Name>
      <Condition>(message.content Like "*unavailable*")</Condition>
   </Step>
  </Response>
...

RaiseFault 政策的名称在 API Monitoring 中显示为 fault.name,而在 Analytics(分析)和 Router 访问日志中显示为 x_apigee_fault_policy。这有助于您轻松地诊断错误的原因。

反模式

在另一个政策已抛出错误后在 FaultRule 内使用 RaiseFault 政策

请考虑下面的示例,其中 API 代理流中的 OAuthV2 政策失败并显示 InvalidAccessToken 错误。失败后,Edge 会将 fault.name 设置为 InvalidAccessToken,进入错误流,并执行任何定义的 FaultRules。在 FaultRule 中,有一个名为 RaiseFault 的 RaiseFault 政策,只要出现 InvalidAccessToken 错误就会发送自定义错误响应。但是,在 FaultRule 中使用 RaiseFault 政策意味着 fault.name 变量会被覆盖,并掩盖故障的真正原因。

<!-- /antipatterns/examples/raise-fault-conditions-2.xml  -->
<FaultRules>
  <FaultRule name="generic_raisefault">
    <Step>
        <Name>RaiseFault</Name>
        <Condition>(fault.name equals "invalid_access_token") or (fault.name equals "InvalidAccessToken")</Condition>
    </Step>
  </FaultRule>
</FaultRules>

在所有条件下在 FaultRule 中使用 RaiseFault 政策

在以下示例中,如果 fault.name 不为 RaiseFault,则系统会执行名为 RaiseFault 的 RaiseFault 政策:

<!-- /antipatterns/examples/raise-fault-conditions-3.xml  -->
<FaultRules>
    <FaultRule name="fault_rule">
        ....
        <Step>
            <Name>RaiseFault</Name>
            <Condition>!(fault.name equals "RaiseFault")</Condition>
        </Step>
    </FaultRule>
</FaultRules>

与第一种情况一样,关键故障变量 fault.namefault.codefault.policy 会被替换为 RaiseFault 政策的名称。在此行为下,未访问显示失败或重现问题的跟踪文件,就几乎无法确定实际导致失败的政策。

使用 RaiseFault 政策在错误流之外返回 HTTP 2xx 响应。

以下示例中,当请求动词为 OPTIONS 时,名为 HandleOptionsRequest 的 RaiseFault 政策会执行:

<!-- /antipatterns/examples/raise-fault-conditions-4.xml  -->
<PreFlow name="PreFlow">
    <Request>
        …
        <Step>
            <Name>HandleOptionsRequest</Name>
            <Condition>(request.verb Equals "OPTIONS")</Condition>
        </Step>
        …
</PreFlow>

其意图是立即将响应返回到 API 客户端,而不处理其他政策。但是,这会导致误导性分析数据,因为故障变量将包含 RaiseFault 政策的名称,导致代理更难以调试。实现所需行为的正确方式是使用具有特殊条件的流,如添加 CORS 支持中所述。

影响

如上所述,使用 RaiseFault 政策会导致使用 RaiseFault 政策的名称而不是失败政策的名称覆盖关键故障变量。在 Analytics(分析)和 NGINX 访问日志中, x_apigee_fault_codex_apigee_fault_policy 变量会被覆盖。在 API Monitoring 中,Fault CodeFault Policy 会被覆盖。此行为使得难以排查问题并确定哪个政策是失败的真正原因。

API Monitoring 的以下屏幕截图中,您可以看到故障代码和故障政策已被覆盖为通用 RaiseFault 值,因此无法根据日志确定失败的根本原因:

最佳做法

当 Edge 政策引发故障并且您希望自定义错误响应消息时,请使用 AllocationMessage 或 JavaScript 政策,而不是 RaiseFault 政策。

应在非错误流中使用 RaiseFault 政策。也就是说,即便在政策或 API 代理的后端服务器上未出现实际错误,也使用 RaiseFault 将特定条件视为错误。例如,您可以使用 RaiseFault 政策指示必填输入参数缺失或语法错误。

如果您希望在故障处理期间检测错误,还可以在故障规则中使用 RaiseFault。举例来说,您的故障处理程序本身可能会导致某一错误,使您想要使用 RaiseFault 就此发出信号。

更多详情