アンチパターン: 不適切な条件下で RaiseFault ポリシーを使用する

RaiseFault ポリシーを使用すると、エラーフローを開始してレスポンスの本文メッセージにエラー変数を設定し、適切なレスポンス ステータス コードを設定できます。また、fault.namefault.typefault.category などの障害に関連するフロー変数の設定にも、RaiseFault ポリシーを使用できます。これらの変数は、分析データと、デバッグに使用されるルーター アクセスログに表示されるため、障害を正確に識別することが重要です。

実際のエラーが別のポリシーまたは API プロキシのバックエンド サーバーで発生していなくても、RaiseFault ポリシーを使用して、特定の条件をエラーとして扱うことができます。たとえば、バックエンドのレスポンスの本文に文字列 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 と表示されます。これにより、エラーの原因を簡単に診断できます。

アンチパターン

別のポリシーがエラーを送出した後、FaultRules 内で RaiseFault ポリシーを使用する

次の例について考えてみましょう。ここでは API プロキシフローの OAuthV2 ポリシーが InvalidAccessToken エラーで失敗しています。障害が発生すると、Edge は fault.nameInvalidAccessToken に設定してエラーフローに入り、定義されたすべての 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.nameRaiseFault がでない場合、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 Access のログでは x_apigee_fault_code 変数と x_apigee_fault_policy 変数が上書きされます。API Monitoring では、Fault CodeFault Policy が上書きされます。この動作により、どのポリシーが障害の真の原因であるかをトラブルシューティングして判断することが難しくなります。

以下の API Monitoring のスクリーンショットでは、障害コードと障害ポリシーが一般的な RaiseFault 値に上書きされており、ログから障害の根本原因を特定できないことがわかります。

ベスト プラクティス

Edge ポリシーで障害が発生し、エラー レスポンス メッセージをカスタマイズする場合は、RaiseFault ポリシーの代わりに AssignMessage または JavaScript ポリシーを使用します。

RaiseFault ポリシーは、エラーのないフローで使用する必要があります。つまり、実際のエラーがポリシーまたは API プロキシのバックエンド サーバーで発生していなくても、RaiseFault ポリシーのみを使用して特定の条件をエラーとして扱います。たとえば、RaiseFault ポリシーを使用して、必須入力パラメータが欠落しているか、構文が正しくないことを通知できます。

障害ルールで RaiseFault を使用して、障害の処理中にエラーを検出することもできます。たとえば、障害ハンドラ自体がエラーを引き起こす可能性があるため、そうしたエラーを RaiseFault によって通知できます。

関連情報