Antimodèle : Utiliser la règle RaiseFault dans des conditions inappropriées

Vous consultez la documentation d'Apigee et d'Apigee hybrid.
Consultez la documentation d'Apigee Edge.

La règle RaiseFault permet aux développeurs d'API de lancer un flux d'erreurs, de définir des variables d'erreur dans un message de réponse et de définir les codes d'état de réponse appropriés. Vous pouvez également utiliser la règle RaiseFault pour définir des variables de flux liées à la défaillance, telles que fault.name, fault.type et fault.category. Comme ces variables sont visibles dans les données d'analyse et dans les journaux d'accès du routeur utilisés pour le débogage, il est important d'identifier précisément la défaillance.

Vous pouvez utiliser la règle RaiseFault pour traiter des conditions spécifiques comme des erreurs, même si une erreur réelle n'a pas été produite dans une autre règle ou sur le serveur backend du proxy d'API. Par exemple, si vous souhaitez que le proxy envoie un message d'erreur personnalisé à l'application cliente lorsque le corps de la réponse backend contient la chaîne unavailable, vous pouvez appeler la règle RaiseFault, comme indiqué dans l'extrait de code ci-dessous :

<!-- /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>
...

Le nom de la règle RaiseFault est visible en tant que fault.name dans l'API Monitoring et en tant que x_apigee_fault_policy dans les journaux d'accès Analytics et Router. Cela permet de diagnostiquer facilement la cause de l'erreur.

Antimodèle

Utiliser la règle RaiseFault dans des règles FaultRules après une erreur générée par une autre règle

Prenons l'exemple ci-dessous, où une règle OAuthV2 du flux de proxy d'API a échoué avec une erreur InvalidAccessToken. Au moment de l'échec, Apigee définit fault.name sur InvalidAccessToken, accède au flux d'erreurs et exécute les règles FaultRules définies. Dans la règle FaultRule, il existe une règle RaiseFault nommée RaiseFault qui envoie une réponse d'erreur personnalisée à chaque fois qu'une erreur InvalidAccessToken se produit. Cependant, l'utilisation de la règle RaiseFault dans une règle FaultRule signifie que la variable fault.name est écrasée et masque la cause réelle de l'échec.

<!-- /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>

Utiliser la règle RaiseFault dans une règle FaultRule dans toutes les conditions

Dans l'exemple ci-dessous, une règle RaiseFault nommée RaiseFault s'exécute si fault.name n'est pas 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>

Comme dans le premier scénario, les variables d'erreur de clé fault.name, fault.code et fault.policy sont remplacées par le nom de la règle RaiseFault. Avec ce comportement, il est quasiment impossible de déterminer la règle à l'origine de l'échec, d'accéder à un fichier de suivi indiquant l'échec ou de reproduire le problème.

Utiliser la règle RaiseFault pour renvoyer une réponse HTTP 2xx en dehors du flux d'erreurs

Dans l'exemple ci-dessous, une règle RaiseFault nommée HandleOptionsRequest s'exécute lorsque le verbe de requête est OPTIONS :

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

L'intention est de renvoyer immédiatement la réponse au client API sans traiter d'autres règles. Toutefois, cela entraîne des erreurs d'analyse trompeuses, car les variables d'erreur contiennent le nom de la règle RaiseFault, ce qui rend le proxy plus difficile à déboguer. La bonne façon de mettre en œuvre le comportement souhaité consiste à utiliser des flux avec des conditions spéciales, comme décrit dans la section Ajouter la compatibilité avec le CORS.

Impact

L'utilisation de la règle RaiseFault telle que décrite ci-dessus entraîne l'écrasement des variables d'erreur de clé par le nom de la règle RaiseFault au lieu du nom de la règle défaillante. Dans les journaux d'accès Analytics et Nginx, les variables x_apigee_fault_code et x_apigee_fault_policy sont écrasées. Dans l'API Monitoring, les variables Fault Code et Fault Policy sont écrasées. Ce comportement rend difficile le dépannage et la sélection de la règle à l'origine de l'échec.

Dans la capture d'écran ci-dessous extraite de la page API Monitoring, vous pouvez voir que le code d'erreur et la règle d'erreur ont été remplacés par des valeurs RaiseFault génériques. Il est donc impossible de déterminer la cause première de l'échec dans les journaux :

À déterminer

Bonne pratique

Lorsqu'une règle Apigee génère une erreur et que vous souhaitez personnaliser le message de réponse d'erreur, utilisez les règles AssignMessage ou JavaScript au lieu de la règle RaiseFault.

La règle RaiseFault doit être utilisée dans un flux sans erreur. En d'autres termes, vous devez utiliser RaiseFault pour traiter une condition spécifique comme une erreur, même si une erreur réelle n'a pas eu lieu dans une règle ou sur le serveur backend du proxy d'API. Par exemple, vous pouvez utiliser la règle RaiseFault pour signaler l'absence de paramètres de saisie obligatoires ou une syntaxe incorrecte.

Vous pouvez également utiliser RaiseFault dans une règle d'erreur si vous souhaitez détecter une erreur lors du traitement d'une erreur. Par exemple, votre gestionnaire d'erreurs peut provoquer une erreur que vous souhaitez signaler à l'aide de RaiseFault.

Documentation complémentaire