Gérer les pannes

Cette page s'applique à Apigee et à Apigee hybrid.

Consultez la documentation d'Apigee Edge.

De nombreuses conditions d'erreur peuvent survenir lorsque les proxys d'API traitent les requêtes en provenance d'applications. Par exemple, les proxys d'API peuvent rencontrer des problèmes réseau lors de la communication avec les services de backend, les applications peuvent présenter des identifiants ayant expiré, le format des messages de requête peut être incorrect, etc.

Lorsqu'une erreur se produit après l'appel d'un proxy d'API par une application cliente, un message d'erreur est renvoyé au client. Par défaut, le client reçoit un message d'erreur souvent difficile à déchiffrer, sans détails ni conseils. Toutefois, si vous souhaitez remplacer les messages d'erreur par défaut par des messages personnalisés plus utiles, et même les enrichir avec des éléments tels que des en-têtes HTTP supplémentaires, vous devez configurer une gestion personnalisée des erreurs dans Apigee.

La gestion personnalisée des erreurs vous permet également d'ajouter des fonctionnalités telles que la journalisation des messages chaque fois qu'une erreur se produit.

Avant d'aborder la mise en œuvre de la gestion des erreurs personnalisée dans vos proxys d'API, il est utile de comprendre comment les erreurs se produisent et comment les proxys d'API réagissent face à elles.

Vidéos

Regardez les vidéos suivantes pour en savoir plus sur la gestion des erreurs.

Vidéo Description
Présentation de la gestion des erreurs et des flux d'erreurs Découvrez la gestion des erreurs et ce qu'il se passe lorsqu'une erreur se produit dans un proxy d'API.
Gérez les erreurs à l'aide de règles d'erreur. Découvrez comment gérer les erreurs à l'aide de règles d'erreur.
Générez les erreurs personnalisées à l'aide de la stratégie RaiseFault Générez des erreurs personnalisées lors de l'exécution de l'API à l'aide de la stratégie RaiseFault.
Définissez des règles de défaillance sur le proxy d'API et sur les points de terminaison cibles Définissez les règles d'erreur dans le proxy d'API et les points de terminaison cibles et comprenez les différences.
Comprenez l'ordre d'exécution des règles de défaillance Comprenez l'ordre d'exécution des règles d'erreur dans le proxy d'API et les points de terminaison cibles.
Définissez une règle d'erreur par défaut Définissez une règle d'erreur par défaut pour gérer les erreurs génériques dans votre API.

Comment les erreurs se produisent-elles ?

Nous aborderons simplement la façon dont les erreurs se produisent. Déterminer la façon dont les erreurs se produisent aide à planifier les différentes situations dans lesquelles vous souhaitez mettre en œuvre une gestion des erreurs personnalisée.

Erreurs automatiques

Un proxy d'API génère automatiquement une erreur dans les situations suivantes :

  • Une stratégie génère une erreur. Par exemple, si un appel d'API envoie une clé ayant expiré, la stratégie VerifyAPIKey génère automatiquement une erreur. Si le nombre d'appels d'API dépasse une certaine limite, la stratégie de quota ou la stratégie SpikeArrest génèrent une erreur. (Consultez la Documentation de référence sur les erreurs de règles pour connaître les types d'erreurs de règles susceptibles d'être générés.)
  • Le flux de messages du proxy d'API présente un problème, par exemple une erreur de routage.
  • Une erreur de backend se produit, par exemple une erreur HTTP due à des échecs au niveau du protocole, des erreurs TLS/SSL ou un service cible indisponible.
  • Il y a une défaillance au niveau du système, telle qu'une exception de mémoire saturée.

Pour plus d'informations sur ces erreurs, consultez la section Classification des pannes de cette rubrique.

Erreurs personnalisées

Dans les cas où il n'y a pas d'erreur automatique, vous pouvez générer une erreur personnalisée, par exemple, si une réponse contient le mot unavailable ou si le code d'état HTTP est supérieur à 201. Pour ce faire, ajoutez une règle RaiseFault à l'emplacement approprié dans un flux de proxy d'API.

Vous pouvez ajouter une règle RaiseFault à un flux de proxy d'API de la même manière que toute autre règle. Dans l'exemple de configuration de proxy suivant, la règle Raise-Fault-1 est associée à la réponse du TargetEndpoint. Si le mot unavailable est présent dans la réponse du service cible, la règle RaiseFault est exécutée et génère une erreur.

<TargetEndpoint name="default">
...
  <Response>
    <Step>
      <Name>Raise-Fault-1</Name>
      <Condition>message.content Like "*unavailable*"</Condition>
    </Step>
  </Response>

L'objectif ici est simplement de vous montrer que vous pouvez générer des erreurs personnalisées. Nous examinerons plus en détail la stratégie RaiseFault dans la section Règles d'erreur et stratégie RaiseFault.

Pour plus d'exemples, consultez les posts suivants de la communauté Apigee :

Que font les proxys d'API en cas d'erreur ?

Voici ce qu'il se passe lorsqu'un proxy génère une erreur.

Quitter le pipeline de proxy

Lorsqu'un proxy d'API rencontre une erreur, quelle que soit la façon dont elle se produit, il ferme le pipeline de flux normal, passe à un état d'erreur et renvoie un message d'erreur à l'application cliente. Lorsque le proxy d'API passe à l'état d'erreur, il ne peut plus revenir au traitement du pipeline de flux normal.

Par exemple, supposons qu'un proxy d'API possède des stratégies dans l'ordre suivant dans la requête ProxyEndpoint :

  1. Vérifier la clé API
  2. Quota
  3. JSON vers XML

Si une erreur se produit lors de la validation de la clé API, le proxy d'API passe à un état d'erreur. Les règles "Quota" et "JSON vers XML" ne sont pas exécutées, le proxy ne poursuit pas l'acheminement vers le TargetEndpoint et un message d'erreur est renvoyé à l'application cliente.

Vérifier les règles d'erreur

Dans l'état d'erreur, les proxys d'API vérifient également la présence des éléments suivants (dans l'ordre) dans la configuration du proxy d'API avant de renvoyer un message d'erreur par défaut à l'application cliente :

  1. Une section <FaultRules>, qui contient la logique permettant de déclencher des messages d'erreur personnalisés (et d'autres stratégies) en fonction de conditions spécifiques que vous définissez.
  2. Une section <DefaultFaultRule> qui déclenche un message d'erreur par défaut dans les situations suivantes :
    • Aucune règle <FaultRules> n'est définie.
    • Aucune stratégie <FaultRules> existante n'est exécutée.
    • L'élément <AlwaysEnforce> est défini sur "true".

En substance, le proxy d'API vous donne la possibilité de renvoyer un message d'erreur personnalisé et de déclencher une autre logique. Si le proxy ne trouve aucune de ces sections, ou si elles existent mais qu'aucune erreur personnalisée n'a été générée, le proxy envoie son propre message par défaut généré par Apigee.

Exemple simple de gestion des erreurs

Commençons par un exemple simple, où un appel à un proxy d'API ne contient pas une clé d'API requise. Par défaut, voici la réponse qui est renvoyée à l'application cliente :

HTTP/1.1 401 Unauthorized
Date: Wed, 20 Jul 2016 19:19:32 GMT
Content-Type: application/json
Content-Length: 150
Connection: keep-alive
Server: Apigee Router

* Connection #0 to host myorg-test.apigee.net left intact
{"fault":{"faultstring":"Failed to resolve API Key variable request.queryparam.apikey","detail":{"errorcode":"steps.oauth.v2.FailedToResolveAPIKey"}}}

Il est possible que les utilisateurs de votre API soient en mesure de déterminer le message d'erreur, mais ce n'est peut-être pas le cas. De nombreuses erreurs par défaut sont subtiles et difficiles à déchiffrer.

En tant que développeur d'API, vous devez modifier ce message pour répondre aux besoins de la personne qui le recevra, qu'il s'agisse d'un développeur d'application iOS ou d'un groupe de test interne ayant ses propres besoins en termes de format de message d'erreur.

Voici un exemple de la façon dont vous devez créer un message d'erreur personnalisé pour gérer cette erreur. Cela nécessite 1) une règle qui définit le message personnalisé, et 2) une règle FaultRule qui exécute la règle lorsque le proxy passe à un état d'erreur.

1. Créer une stratégie définissant le message personnalisé

Commencez par créer une règle qui définit le message d'erreur personnalisé. Vous pouvez utiliser n'importe quel type de règle, par exemple une règle AssignMessage, qui permet de définir une charge utile et des en-têtes HTTP facultatifs tels que le code d'état et l'expression de motif. La règle AssignMessage est idéale dans ce cadre. Elle vous permet de contrôler la charge utile des messages, de définir un code d'état HTTP différent, de définir une autre expression de motif HTTP et d'ajouter des en-têtes HTTP.

Vous n'avez pas besoin d'associer la règle à un flux. Il vous suffit de la créer, comme décrit dans la section Créer la règle.

Voici un exemple de stratégie AssignMessage qui :

  • Renvoie un message JSON.
  • Définit un code d'état HTTP (911, qui est un code d'état n'existant manifestement pas mais servant à illustrer la flexibilité dont vous disposez). Le code d'état s'affiche dans l'en-tête HTTP.
  • Définit une expression de motif HTTP (pour remplacer l'expression par défaut Unauthorized correspondant à cette erreur de clé API manquante). L'expression de motif indiquée s'affiche à côté du code d'état dans l'en-tête HTTP.
  • Crée et renseigne un nouvel en-tête HTTP appelé invalidKey.
<AssignMessage async="false" continueOnError="false" enabled="true" name="invalid-key-message">
    <DisplayName>Invalid key message</DisplayName>
    <Set>
        <Payload contentType="application/json">{"Citizen":"Where's your API key? I don't see it as a query parameter"}</Payload>
        <StatusCode>911</StatusCode>
    </Set>
    <Add>
        <Headers>
            <Header name="invalidKey">Invalid API key! Call the cops!</Header>
        </Headers>
    </Add>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

Lorsque cette règle est exécutée, la réponse à l'application cliente se présente comme suit. Comparez-la à la réponse par défaut indiquée précédemment.

HTTP/1.1 911 Rejected by API Key Emergency Services
Date: Wed, 20 Jul 2016 18:42:36 GMT
Content-Type: application/json
Content-Length: 35
Connection: keep-alive
invalidKey: Invalid API key! Call the cops!
Server: Apigee Router

* Connection #0 to host myorg-test.apigee.net left intact
{"Citizen":"Where's your API key? I don't see it as a query parameter."}

Oui, c'est un peu loufoque, mais cela montre les possibilités dont vous disposez. Au moins, le développeur qui reçoit le message sait maintenant qu'il a oublié d'inclure une clé API en tant que paramètre de requête.

Mais comment cette règle est-elle exécutée ? La section suivante vous explique comment.

2. Créer la règle <FaultRule> qui déclenchera la stratégie

Dans les sections <ProxyEndpoint> ou <TargetEndpoint> de la configuration du proxy, vous ajouterez un bloc XML <FaultRules> contenant une ou plusieurs sections <FaultRule> individuelles. Chaque règle d'erreur représente une erreur différente que vous souhaitez gérer. Dans cet exemple simple, nous utilisons une seule règle d'erreur pour vous montrer de quoi celle-ci est constituée.

Vous devez également ajouter un <DefaultFaultRule> pour fournir un message d'erreur général personnalisé si aucune de vos règles d'erreur n'est exécutée.

Exemple

<ProxyEndpoint name="default">
...
    <FaultRules>
       <FaultRule name="invalid_key_rule">
            <Step>
                <Name>invalid-key-message</Name>
            </Step>
            <Condition>(fault.name = "FailedToResolveAPIKey")</Condition>
        </FaultRule>
    </FaultRules>
    <DefaultFaultRule name="default-fault">
        <Step>
            <Name>Default-message</Name>
        </Step>
    </DefaultFaultRule>

Points essentiels :

  • Les règles d'erreur sont définies dans ProxyEndpoint. C'est important. Obtenez plus d'informations sur l'insertion de règles d'erreur dans ProxyEndpoint et TargetEndpoint ultérieurement.
  • <Name> : nom de la règle à exécuter. Le nom provient de l'attribut name de la stratégie sur l'élément parent, comme indiqué précédemment dans l'exemple de stratégie.
  • <Condition> : Apigee évalue la condition et n'exécute la règle que si la condition est vraie. Si plusieurs règles FaultRules sont vérifiées, Apigee exécute la première règle qui est vraie. (Important : L'ordre d'évaluation des règles d'erreur, de haut en bas ou de bas en haut, diffère entre le TargetEndpoint et le ProxyEndpoint, comme décrit dans la section Règles FaultRules multiples et logique d'exécution.) Si vous n'incluez pas de condition, la règle FaultRule est automatiquement vraie. Ce n'est pas une bonne pratique. Chaque règle FaultRule doit avoir sa propre condition.

  • <DefaultFaultRule> : si aucune règle d'erreur personnalisée n'est exécutée, <DefaultFaultRule> est exécutée, envoyant un message personnalisé plus générique au lieu du message par défaut obscur généré par Apigee. Une <DefaultFaultRule> peut également avoir une <Condition>, mais dans la plupart des cas, vous n'en incluez pas, car vous souhaitez l'exécuter en dernier recours quoi qu'il en soit.

    La règle DefaultFaultRule sert généralement à renvoyer un message d'erreur générique pour toute erreur inattendue. Par exemple, il peut s'agir d'un message contenant des coordonnées de l'assistance technique. Cette réponse par défaut sert à la fois à fournir des informations conviviales aux développeurs tout en masquant les URL de backend ou d'autres informations susceptibles d'être utilisées pour compromettre le système.

Plusieurs règles d'erreur et logique d'exécution

Dans la section Exemple de gestion des erreurs simple, nous avons utilisé un exemple simple d'une règle d'erreur et d'une condition uniques. Dans un projet d'API réel contenant toutes les erreurs possibles, vous risquez de créer plusieurs règles d'erreur et une règle d'erreur par défaut dans <ProxyEndpoint> et <TargetEndpoint>. Au final toutefois, une seule règle d'erreur est exécutée lorsqu'un proxy d'API passe à l'état d'erreur.

Cette section décrit la logique qu'Apigee utilise pour gérer les règles d'erreur, de la façon dont elle s'applique au niveau d'une seule règle d'erreur à exécuter à la façon dont les conditions d'étape internes sont gérées lorsque leur règle d'erreur est déclenchée. Cette section indique également quand définir des règles d'erreur dans <ProxyEndpoint> par rapport à <TargetEndpoint>, et décrit la relation entre les règles d'erreur et la règle RaiseFault.

Exécution des règles d'erreur

En résumé, voici la logique utilisée par Apigee lorsqu'un proxy d'API passe à un état d'erreur. Notez qu'il existe une légère différence entre l'évaluation FaultRules dans le ProxyEndpoint et dans le TargetEndpoint.

  1. Apigee évalue les règles d'erreur dans ProxyEndpoint ou TargetEndpoint, selon l'endroit où l'erreur s'est produite :
    • ProxyEndpoint - Apigee commence par la <FaultRule> du bas dans le fichier XML de configuration, puis avance vers le haut, évaluant la <Condition> de chaque <FaultRule> (la condition externe, et non les conditions <Step> internes).
    • TargetEndpoint - Apigee commence par la <FaultRule> du haut dans le fichier XML de configuration, puis avance vers le bas, évaluant la <Condition> de chaque <FaultRule> (la condition externe, et non les conditions <Step> internes).
  2. Exécute la première règle d'erreur dont la condition est vraie. Si une règle d'erreur n'a pas de condition, sa valeur est "true" par défaut.
    • Lorsqu'une règle d'erreur est exécutée, toutes les étapes de la règle d'erreur sont évaluées dans l'ordre, de haut en bas dans le fichier XML de configuration. Les étapes sans condition sont automatiquement exécutées (les règles sont exécutées), et les étapes dont la <Condition> renvoie la valeur "true" sont exécutées (les conditions renvoyant la valeur code ne sont pas exécutées).
    • Si une règle d'erreur est exécutée, mais qu'aucune étape dans la règle d'erreur n'est exécutée (parce que leurs conditions renvoient la valeur code), le message d'erreur par défaut généré par Apigee est renvoyé à l'application cliente. La <DefaultFaultRule> n'est pas exécutée, car Apigee a déjà exécuté sa seule règle d'erreur.

  3. Si aucune règle d'erreur n'est exécutée, Apigee exécute la <DefaultFaultRule>, le cas échéant.

Voici des exemples de commentaires intégrés.

Exécution du proxyEndpoint

L'évaluation des règles d'erreur ProxyEndpoint se faisant de bas en haut, commencez donc à lire à la dernière règle d'erreur dans l'exemple suivant et avancez vers le haut. Examinez la dernière règle d'erreur par défaut en dernier.

<ProxyEndpoint name="default">
...
    <FaultRules>
<!-- 3. This FaultRule is automatically TRUE, because there's no outer
     condition. But because the FaultRule just below this got
     executed (bottom-to-top evaluation in a ProxyEndpoint), Apigee
     doesn't even evaluate this FaultRule.
     Note that it's not a best practice to have a FaultRule without
     an outer condition, which automatically makes the FaultRule true. -->
        <FaultRule name="random-error-message">
            <Step>
                <Name>Random-fault</Name>
            </Step>
        </FaultRule>
<!-- 2. Let's say this fault is TRUE. The Quota policy threw a QuotaViolation
     error. This is the first FaultRule to be TRUE, so it's executed.
     Now the Steps are evaluated, and for the ones whose conditions
     evaluate to TRUE, their policies are executed. Steps without
     conditions are automatically true. -->
<FaultRule name="over_quota">
            <Step>
                <Name>developer-over-quota-fault</Name>
                <Condition>(ratelimit.developer-quota-policy.exceed.count GreaterThan "0")</Condition>
            </Step>
            <Step>
                <Name>global-over-quota-fault</Name>
                <Condition>(ratelimit.global-quota-policy.exceed.count GreaterThan "0")</Condition>
            </Step>
            <Step>
                <Name>log-error-message</Name>
            </Step>
            <Condition>(fault.name = "QuotaViolation")</Condition>
        </FaultRule>
<!-- 1. Because this is the ProxyEndpoint, Apigee looks at this FaultRule
     first. But let's say this FaultRule is FALSE. A policy did not
     throw a FailedToResolveAPIKey error. Apigee moves UP to check
     the next FaultRule. -->
        <FaultRule name="invalid_key_rule">
            <Step>
                <Name>invalid-key-message</Name>
            </Step>
            <Condition>(fault.name = "FailedToResolveAPIKey")</Condition>
        </FaultRule>
    </FaultRules>

<!-- If no <FaultRule> is executed, the <DefaultFaultRule> is executed.
     If a FaultRule is executed, but none of its Steps are executed,
     The DefaultFaultRule is not executed (because Apigee has already
     executed its one FaultRule). -->
    <DefaultFaultRule name="default-fault">
        <Step>
            <Name>Default-message</Name>
        </Step>
    </DefaultFaultRule>

Exécution de TargetEndpoint

L'évaluation des règles d'erreur TargetEndpoint se faisant de haut en bas, commencez donc à lire à la première règle d'erreur dans l'exemple suivant et avancez vers le bas. Examinez la dernière règle d'erreur par défaut en dernier.

<TargetEndpoint name="default">
...
    <FaultRules>
<!-- 1. Because this is the TargetEndpoint, Apigee looks at this FaultRule
     first. Let's say this FaultRule is FALSE.
     A policy did not throw a FailedToResolveAPIKey error.
     Apigee moves down to the next FaultRule. -->
        <FaultRule name="invalid_key_rule">
            <Step>
                <Name>invalid-key-message</Name>
            </Step>
            <Condition>(fault.name = "FailedToResolveAPIKey")</Condition>
        </FaultRule>
<!-- 2. Let's say this fault is TRUE. The Quota policy threw a QuotaViolation
     error. This is the first FaultRule to be TRUE, so it's executed.
     Now the Steps are evaluated, and for the ones whose conditions
     evaluate to TRUE, their policies are executed. Steps without
     conditions are automatically true. -->
        <FaultRule name="over_quota">
            <Step>
                <Name>developer-over-quota-fault</Name>
                <Condition>(ratelimit.developer-quota-policy.exceed.count GreaterThan "0")</Condition>
            </Step>
            <Step>
                <Name>global-over-quota-fault</Name>
                <Condition>(ratelimit.global-quota-policy.exceed.count GreaterThan "0")</Condition>
            </Step>
            <Step>
                <Name>log-error-message</Name>
            </Step>
            <Condition>(fault.name = "QuotaViolation")</Condition>
        </FaultRule>
<!-- 3. This FaultRule is automatically TRUE, because there's no outer
     condition. But because the FaultRule just above this got
     executed (top-to-bottom evaluation in a TargetEndpoint), Apigee
     doesn't even evaluate this FaultRule.
     Note that it's not a best practice to have a FaultRule without
     an outer condition, which automatically makes the FaultRule true. -->
        <FaultRule name="random-error-message">
            <Step>
                <Name>Random-fault</Name>
            </Step>
        </FaultRule>
    </FaultRules>

<!-- If no <FaultRule> is executed, the <DefaultFaultRule> is executed.
     If a FaultRule is executed, but none of its Steps are executed,
     The DefaultFaultRule is not executed (because Apigee has already
     executed its one FaultRule). -->
    <DefaultFaultRule name="default-fault">
        <Step>
            <Name>Default-message</Name>
        </Step>
    </DefaultFaultRule>

Ordre des règles d'erreur

Comme vous pouvez le voir dans l'exemple précédent, l'ordre dans lequel vous placez vos règles d'erreur est important, selon que l'erreur se produit dans ProxyEndpoint ou dans TargetEndpoint.

Exemple :

Ordre dans ProxyEndpoint Ordre dans TargetEndpoint

Dans l'exemple suivant, étant donné que l'évaluation se fait de bas en haut, la règle d'erreur 3 est exécutée, ce qui signifie que les règles d'erreur 2 et 1 ne sont pas évaluées.

5. Règle d'erreur 1 : FALSE

4. Règle d'erreur 2 : TRUE

3. Règle d'erreur 3 : TRUE

2. Règle d'erreur 4 : FALSE

1. Règle d'erreur 5 : FALSE

Dans l'exemple suivant, étant donné que l'évaluation se fait de haut en bas, la règle d'erreur 2 est exécutée, ce qui signifie que les règles d'erreur 3, 4 et 5 ne sont pas évaluées.

1. Règle d'erreur 1 : FALSE

2. Règle d'erreur 2 : TRUE

3. Règle d'erreur 3 : TRUE

4. Règle d'erreur 4 : FALSE

5. Règle d'erreur 5 : FALSE

Règles à inclure

Vous pouvez exécuter toutes les règles d'une règle FaultRule en les plaçant dans des étapes. Par exemple, vous pouvez exécuter une règle AssignMessage pour mettre en forme une réponse destinée à l'application cliente, puis consigner un message avec la règle MessageLogging. Les règles sont exécutées dans l'ordre dans lequel vous les avez placées (de haut en bas dans le fichier XML).

Les règles d'erreur sont déclenchées UNIQUEMENT à l'état d'erreur (au niveau de continueOnError)

L'en-tête peut donner l'impression que nous nous répétons, mais il existe une nuance particulière à prendre en compte concernant une erreur de proxy entraînant le passage d'une API à un état d'erreur, ou plutôt son non passage à un état d'erreur : l'attribut continueOnError sur une stratégie.

En résumé : un proxy d'API évalue <FaultRules> et <DefaultFaultRule> uniquement si le proxy est passé à un état d'erreur. Cela signifie que même si une condition de règle d'erreur renvoie la valeur "true", elle ne sera pas déclenchée si le proxy n'est pas dans un état d'erreur.

Toutefois, voici un exemple d'erreur se produisant et de proxy ne passant pas à un état d'erreur. Sur n'importe quelle stratégie, vous pouvez définir un attribut sur l'élément parent appelé continueOnError. Cet attribut est très important pour la gestion des erreurs, car il détermine si le proxy passe ou non à un état d'erreur en cas d'échec de la stratégie. Dans la plupart des cas, vous devez conserver la valeur par défaut continueOnError="false", qui place le proxy dans un état d'erreur si la stratégie échoue et la gestion d'erreur personnalisée est déclenchée. Toutefois, si continueOnError="true" (par exemple, si vous ne souhaitez pas que l'échec d'un appel de service arrête l'exécution du proxy), le proxy ne passe pas à un état d'erreur en cas d'échec de cette stratégie et le proxy n'examine pas vos règles d'erreur.

Pour plus d'informations sur la journalisation des erreurs lorsque continueOnError="true", consultez la section Gérer les erreurs de règles dans le flux actuel.

Où définir les règles d'errur : ProxyEndpoint ou TargetEndpoint

Lorsqu'un proxy d'API rencontre une erreur, celle-ci se produit dans <ProxyEndpoint> (requête de ou réponse à l'application cliente) ou dans <TargetEndpoint> (requête à ou réponse du service cible). Chaque fois que cette erreur se produit, Apigee recherche des règles d'erreur.

Par exemple, si aucun serveur cible n'est disponible (code d'état HTTP 503), le proxy d'API passe à un état d'erreur dans la réponse <TargetEndpoint> et le flux de proxy d'API normal ne continue pas vers <ProxyEndpoint>. Si des règles d'erreur sont définies uniquement dans le <ProxyEndpoint>, elles ne traitent pas cette erreur.

Voici un autre exemple. Si une stratégie RaiseFault sur la réponse <ProxyEndpoint> déclenche une erreur, une règle d'erreur dans <TargetEndpoint> ne sera pas exécutée.

Stratégie FaultRules ou RaiseFault

Les règles d'erreur et la règle RaiseFault peuvent donner l'impression qu'il s'agit de deux solutions équivalentes pour gérer les défaillances, et de certaines manières, c'est le cas. Mais elles fonctionnent aussi en synergie. Cette section explique la relation entre les deux. Comprendre cette relation devrait vous aider à concevoir votre gestion des défaillances, en particulier si vous souhaitez utiliser ces deux règles.

En bref :

  • Les règles d'erreur sont toujours évaluées lorsqu'un proxy d'API passe à un état d'erreur.
  • La stratégie RaiseFault permet de placer un proxy d'API dans un état d'erreur lorsqu'une erreur ne se serait autrement pas produite.

    Par exemple, si vous souhaitez générer une erreur lorsque le code d'état HTTP de la réponse du service cible est supérieur à 200, vous devez ajouter une règle RaiseFault dans votre flux de réponse. Celle-ci se présente alors sous la forme suivante :

    <TargetEndpoint name="default">
        <PreFlow name="PreFlow">
    ...
            <Response>
                <Step>
                    <Name>Raise-Fault-1</Name>
    <!-- If the condition is true, the Raise-Fault-1 policy gets executed -->
                    <Condition>(response.status.code GreaterThan "200")</Condition>
                </Step>
            </Response>
    

    La stratégie RaiseFault envoie également un message d'erreur à l'application cliente.

Que se passe-t-il lorsqu'une règle RaiseFault déclenche une erreur, ce qui place alors le proxy dans un état d'erreur, ce qui à son tour déclenche potentiellement l'exécution d'une règle FaultRule ? C'est là que les choses deviennent un peu délicates. Si la règle RaiseFault renvoie un message d'erreur et une règle FaultRule se déclenche et renvoie un message d'erreur, qu'est-ce qui est renvoyé à l'application cliente ?

  • Étant donné que la règle d'erreur ou règle d'erreur par défaut est exécutée après la stratégie RaiseFault, les données de réponse de règle d'erreur l'emportent.
  • Les données de réponse de la stratégie RaiseFault (code d'état, expression de motif ou charge utile du message) sont utilisées si elles ne sont pas définies par la règle d'erreur ou règle d'erreur par défaut.
  • Si les règles RaiseFault et FaultRule ajoutent toutes deux des en-têtes HTTP personnalisés, les données des deux sont incluses dans la réponse. Des noms d'en-têtes en double créent un en-tête comportant plusieurs valeurs.

Voici un exemple de ce qui est défini par une stratégie RaiseFault et une règle d'erreur, ainsi que les éléments renvoyés à l'application cliente. Les exemples sont conçus pour des raisons de concision, et non pour les bonnes pratiques.

Ce qui est défini par une règle RaiseFault et une règle FaultRule.

L'application cliente reçoit :


Status Code: 468
Reason Phrase: Something happened
Payload: {"Whoa":"Sorry."}
Header:
  errorNote: woops,gremlins

<- La stratégie de règles d'erreur définit les éléments suivants :


Status Code: [none]
Reason Phrase: Something happened
Payload: {"Whoa":"Sorry."}
Header:
  errorNote: gremlins

<- La stratégie RaiseFault définit les éléments suivants :


Status Code: 468
Reason Phrase: Can't do that
Payload: {"DOH!":"Try again."}
Header:
  errorNote: woops

Conditions de construction

Les conditions sont la clé de l'exécution des règles d'erreur. Vous créez des conditions de règle d'erreur de la même manière que pour d'autres conditions dans Apigee, telles que les flux conditionnels ou les conditions RaiseFault.

Pour mettre en contexte le reste de cette section, voici un exemple de règle d'erreur qui présente une condition de règle d'erreur externe et une condition d'étape interne.

<FaultRule name="invalid_key_rule">
    <Step>
        <Name>invalid-key-message</Name>
        <Condition>oauthV2.Verify-API-Key-1.failed = true</Condition>
    </Step>
    <Condition>fault.name = "FailedToResolveAPIKey"</Condition>
</FaultRule>

Variables spécifiques aux erreurs liées aux stratégies

Les variables fault.name et {policy_namespace}.{policy_name}.failed sont disponibles lorsqu'une règle génère une erreur.

fault.name

Lorsqu'une stratégie échoue, interceptez l'erreur dans une condition à l'aide de la variable fault.name. Exemple :

<Condition>fault.name = "policy_error_name"</Condition>

Le nom de l'erreur s'affiche dans le message d'erreur par défaut. Par exemple, dans le code suivant, le nom de l'erreur est FailedToResolveAPIKey. Dans ce cas, une variable de flux appelée fault.name est définie sur la valeur FailedToResolveAPIKey.

{"fault":{"faultstring":"Failed to resolve API Key variable request.queryparam.apikey","detail":{"errorcode":"steps.oauth.v2.FailedToResolveAPIKey"}}}

Ainsi, la condition se présentera comme suit :

<Condition>fault.name = "FailedToResolveAPIKey"</Condition>

Pour obtenir la liste des erreurs de règles, consultez la documentation de référence sur les erreurs de règles.

{policy_namespace}.{policy_name}.failed

La variable *.failed est disponible lorsqu'une règle échoue. Vous trouverez ci-dessous des exemples de variables *.failed pour différentes règles. Pour les espaces de noms de règles, consultez les variables de flux dans la documentation de référence sur les règles.

Autres variables disponibles

Lorsqu'un proxy d'API passe à l'état d'erreur, les seules variables disponibles à utiliser dans les conditions sont les suivantes :

  • Variables de la stratégie qui a échoué.
  • Variables de message HTTP qui existent au point de défaillance. Par exemple, si une erreur est générée dans la réponse, une règle FaultRule du <TargetEndpoint> peut utiliser les données HTTP response.status.code, message.content, error.content, etc. Si une règle de quota a échoué, vous pouvez utiliser la variable ratelimit.{quota_policy_name}.exceed.count. Utilisez l'outil Debug et la documentation de référence sur les règles pour vous aider à déterminer les variables et les données HTTP disponibles.

En savoir plus

Bonnes pratiques pour la gestion des erreurs

La gestion des erreurs est une tâche de conception architecturale majeure pour le développement de proxys d'API. Il est important de prendre le temps de comprendre comment et quand vous allez gérer des erreurs, de déterminer ce que diront les messages d'erreur et de concevoir les formats des messages d'erreur. Une fois que vous avez clarifié ces aspects, utilisez ces bonnes pratiques pour vous aider à mettre en œuvre la gestion des erreurs.

Voici quelques bonnes pratiques à suivre pour concevoir et créer une gestion des erreurs :

  • Dans les règles FaultRules, vous pouvez spécifier n'importe quel type d'erreur. Le modèle le plus courant consiste à utiliser la règle AssignMessage pour définir des éléments spécifiques dans la réponse d'erreur en attente. Vous pouvez également utiliser AssignMessage pour définir des variables utilisées à d'autres fins, par exemple pour les variables référencées par des règles de journalisation exécutées dans le PostClientFlow ou les FlowHooks. Envisagez également de consigner un message, par exemple avec la règle MessageLogging ou la règle ServiceCallout, si vous souhaitez consigner des erreurs spécifiques dans des conditions d'erreur spécifiques.
  • Ne spécifiez pas de règles RaiseFault en tant qu'étapes dans une FaultRule. Il est préférable d'utiliser les règles AssignMessage pour définir ou modifier des éléments de message, y compris la charge utile, les en-têtes ou le code d'état.
  • Pour chaque règle FaultRule, ou pour toutes les règles FaultRule sauf la dernière évaluée, fournissez une <Condition> externe associée en tant qu'enfant de l'élément <FaultRule>. La condition d'exécution d'une règle FaultRule sans condition explicite spécifiée sera implicitement définie sur true. Un élément <Condition> associé en tant qu'enfant d'un élément <Step> n'est pas utilisé pour déterminer si la condition d'exécution de la règle d'erreur renvoie la valeur true ou false. Les conditions Step sont évaluées seulement après qu'Apigee a exécuté la règle FaultRule qui les contient. Dans une règle FaultRule, il est courant d'avoir plusieurs étapes avec des règles AssignMessage (ou d'autres règles), chacune ayant une condition Step.
  • Pour gérer les erreurs dans plusieurs règles du même type (par exemple, plusieurs règles de quota), créez une règle FaultRule par erreur de règle que vous êtes susceptible de recevoir, puis distinguez les erreurs distinctes avec les conditions associées aux Steps. Par exemple, créez une règle FaultRule pour gérer une erreur dans les règles de quota, telle que QuotaViolation, et une règle FaultRule distincte pour InvalidApiKey. (Consultez la documentation de référence sur les erreurs liées aux règles pour connaître les erreurs liées aux règles. Au fur et à mesure que vous découvrez d'autres erreurs à traiter, vous pouvez revenir et les ajouter à vos règles FaultRules. Un fonctionnement itératif est tout à fait acceptable, même si cela nécessite un redéploiement du proxy.) Cette approche vous permet d'identifier le même type d'erreur quelle que soit la règles qui génère l'erreur et de rendre le XML de vos règles FaultRules plus efficace.

    Les conditions Step internes vous permettent un contrôle plus précis. Par exemple, si vous appliquez à la fois un quota individuel de développeur et un quota global avec deux règles dans votre flux de requête, définissez la condition FaultRule externe de façon à ce qu'elle se déclenche sur l'erreur QuotaViolation (qui est générée lorsque le quota dépasse la limite dans les deux cas). Définissez ensuite les conditions Step pour évaluer les variables exceed.countspécifiques dans vos deux règles de quota. Seule l'erreur pertinente est envoyée au client (dépassement du quota de développeur ou du quota global). Voici un exemple de cette configuration :

    <FaultRule name="over_quota">
      <!-- This condition catches a QuotaViolation in *any* Quota policy -->
      <Condition>fault.name = "QuotaViolation"</Condition>
      <Step>
        <Name>AM-developer-over-quota-fault</Name>
        <Condition>ratelimit.developer-quota-policy.exceed.count GreaterThan 0</Condition>
      </Step>
      <Step>
        <Name>AM-global-over-quota-fault</Name>
        <Condition>ratelimit.global-quota-policy.exceed.count GreaterThan 0</Condition>
      </Step>
    </FaultRule>
    

    Pour voir un autre exemple, consultez cette discussion sur la gestion des erreurs liées aux règles.

  • Pour gérer les erreurs lorsque vous utilisez une seule stratégie d'un type, considérez une règle d'erreur unique qui est exécutée en cas d'échec de cette stratégie, et incluez plusieurs étapes correspondant à chaque erreur possible. Votre fichier XML demeure plus simple en utilisant une seule règle d'erreur plutôt que plusieurs (une pour chaque type d'erreur). Par exemple, vous pouvez spécifier l'exécution de différentes étapes de la règle AssignMessage selon différentes conditions, comme suit :

    <FaultRule name="raise-fault-3">
      <!-- This condition catches *any* error in the Verify-API-Key-1 policy. -->
      <Condition>oauthV2.Verify-API-Key-1.failed = "true"</Condition>
      <!-- This first step always executes, which handles errors you haven't mapped with inner conditions. -->
      <Step>
        <Name>AM-Generic-Key-Fault</Name>
      </Step>
      <Step>
        <Name>AM-API-Key-NotFound</Name>
        <Condition>fault.name = "FailedToResolveAPIKey"</Condition>
      </Step>
      <Step>
        <Name>AM-API-Key-Invalid</Name>
        <Condition>fault.name = "InvalidApiKey"</Condition>
      </Step>
    </FaultRule>
    
  • Ajouter les règles d'erreur où les erreurs se produiront (côté client <ProxyEndpoint> ou côté cible <TargetEndpoint>). Incluez des règles d'erreur pour chaque stratégie qui s'affiche à chaque emplacement.
  • Lorsque vous utilisez des stratégies RaiseFault conjointement avec des règles d'erreur, coordonnez les données de réponse renvoyées lorsque la stratégie RaiseFault et une règle d'erreur renvoient des données. Par exemple, si vous avez une règle RaiseFault qui définit le code d'état HTTP, ne configurez pas également une étape AssignMessage dans une règle FaultRule qui réinitialise le code d'état. Le pire pouvant se produire est que le code d'état par défaut soit renvoyé à l'application cliente.
  • L'élément <DefaultFaultRule> complète l'élément <FaultRules> pour vous donner davantage de contrôle sur les règles exécutées par le proxy lorsqu'il gère un état d'erreur. Si vous spécifiez un élément <DefaultFaultRule>, il s'exécutera si l'une des conditions suivantes (ou les deux) est remplie :

    • Aucune autre règle FaultRule n'a été exécutée. Il s'agit d'un cas particulier si aucun élément <FaultRules> n'est configuré.
    • Si l'élément enfant <AlwaysEnforce> de <DefaultFaultRule> est défini sur "true".

    Vous pouvez également spécifier un élément <Condition> sur un élément <DefaultFaultRule>. Cela peut vous permettre d'exclure son exécution en fonction d'un certain état de la requête ou du message d'erreur en attente, par exemple si un en-tête spécifique est présent ou manquant.

    Utilisez une <DefaultFaultRule> avec <AlwaysEnforce> défini sur true si vous souhaitez que le proxy exécute toujours une ou plusieurs de vos règles, indépendamment de l'exécution d'une règle FaultRule antérieure. Voici un scénario possible : supposons que vous souhaitiez injecter un en-tête dans la réponse dans tous les cas, que la requête de proxy ait généré ou non une erreur, et que l'erreur ait été gérée ou non précédemment. Il vous faudrait alors associer une règle AssignMessage appropriée dans la section <PostFlow>/<Response>, et associer également la même règle dans la <DefaultFaultRule> avec <AlwaysEnforce> défini sur true.

Schéma de gestion centralisée et réutilisable des erreurs

Un modèle de traitement des erreurs pour les proxys Apigee décrit un modèle de gestion centralisée des erreurs sans duplication de code.

Créer des règles d'erreur

Pour ajouter une règle d'erreur, vous devez modifier la configuration XML de ProxyEndpoint ou TargetEndpoint. Vous pouvez utiliser l'interface utilisateur Apigee pour effectuer cette modification dans le volet Code de la vue de développeur pour un proxy d'API, ou modifier le fichier XML qui définit le ProxyEndpoint ou le TargetEndpoint.

Si vous créez des règles d'erreur dans l'interface utilisateur Apigee, créez d'abord les règles que vous souhaitez exécuter, puis ajoutez-les à la configuration de règle d'erreur. (Une erreur s'affiche dans l'interface utilisateur si vous essayez d'enregistrer une règle d'erreur faisant référence à une stratégie qui n'a pas encore été créée.)

Ajout de stratégies à une FaultRule

Bien que vous puissiez placer n'importe quelle stratégie dans la règle d'erreur, vous utilisez généralement la stratégie AssignMessage pour générer un message de réponse personnalisé pour une condition d'erreur. La stratégie AssignMessage vous permet de configurer une réponse HTTP avec des éléments de charge utile, de code d'état HTTP, d'en-têtes et d'expression de motif.

L'exemple ci-dessous présente une configuration de stratégie AssignMessage type :

<AssignMessage name="AM-Invalid-Key">
  <Set>
      <Payload contentType="text/plain">That is an error.</Payload>
      <StatusCode>401</StatusCode>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

Notez qu'elle ne spécifie pas d'élément <AssignTo>. Cela signifie qu'elle sera attribuée au message ambiant, selon l'endroit où la règle est associée.

Vous pouvez maintenant utiliser cette stratégie dans votre règle d'erreur. Notez la façon dont vous référencez la stratégie AssignMessage par nom dans la règle d'erreur :

<ProxyEndpoint name="default">
  ...
  <FaultRules>
    <FaultRule name="invalid_key_rule">
      <Step>
        <Name>AM-Invalid-Key</Name>
      </Step>
      <Condition>fault.name = "InvalidApiKey"</Condition>
    </FaultRule>
  </FaultRules>
</ProxyEndpoint>

Lorsque vous déployez la configuration ci-dessus, le proxy d'API exécute la règle AssignMessage appelée AM-Invalid-Key chaque fois qu'une application présente une clé API non valide.

Vous pouvez exécuter plusieurs stratégies dans une règle d'erreur, comme illustré dans l'exemple suivant :

<ProxyEndpoint name="default">
  ...
  <FaultRules>
    <FaultRule name="invalid_key_rule">
      <Step>
        <Name>AM-Invalid-Key</Name>
      </Step>
      <Step>
        <Name>policy2</Name>
      </Step>
      <Step>
        <Name>policy3</Name>
      </Step>
      <Condition>fault.name = "InvalidApiKey"</Condition>
    </FaultRule>
  </FaultRules>
</ProxyEndpoint>

Les stratégies s'exécutent dans l'ordre défini. Par exemple, vous pouvez utiliser la stratégie MessageLogging, la stratégie ExtractVariables, la stratégie AssignMessage ou toute autre stratégie dans la règle d'erreur. Notez que le traitement de la règle d'erreur s'arrête immédiatement si l'une des situations suivantes se produit :

  • Une stratégie de la règle d'erreur entraîne une erreur.
  • Une stratégie de la règle d'erreur est de type RaiseFault.

Définir le message d'erreur personnalisé renvoyé par une règle d'erreur

Il est recommandé de définir des réponses d'erreur claires en provenance de vos API. Vous fournissez ainsi des informations cohérentes et utiles à vos clients.

L'exemple de stratégie AssignMessage suivant utilise les tags <Payload> et <StatusCode> pour définir la réponse d'erreur personnalisée renvoyée au client au niveau d'une erreur InvalidApiKey (voir l'exemple de règle d'erreur précédent).

<AssignMessage name="AM-Invalid-Key">
  <Set>
    <Payload contentType="text/plain">You have attempted to access a resource without the correct authorization.
       Contact support at support@mycompany.com.</Payload>
    <StatusCode>401</StatusCode>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

Cette réponse inclut les éléments suivants :

  • Charge utile contenant le message d'erreur ainsi qu'une adresse e-mail permettant de contacter l'assistance.
  • Le code d'état HTTP renvoyé dans la réponse.
  • L'expression du motif, qui est une brève description de l'erreur.

Créer une règle d'erreur par défaut

Une règle d'erreur par défaut agit comme un gestionnaire d'exceptions pour toute erreur qui n'est pas explicitement gérée par une autre règle d'erreur. Si les conditions de toutes les règles d'erreur ne correspondent pas à l'erreur, la règle d'erreur par défaut gère l'erreur. Activez la gestion des erreurs par défaut en ajoutant le tag <DefaultFaultRule> en tant qu'élément enfant d'un ProxyEndpoint ou d'un TargetEndpoint.

Par exemple, la configuration TargetEndpoint ci-dessous définit une règle d'erreur par défaut qui appelle une stratégie nommée AM-Return-Generic-Error :

<TargetEndpoint name="default">
  ...
  <FaultRules>
    ...
  </FaultRules>

  <DefaultFaultRule name="fault-rule">
    <Step>
      <Name>AM-Return-Generic-Error</Name>
    </Step>
  </DefaultFaultRule>

  <HTTPTargetConnection>
    <URL>https://mytarget.example.net</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

La règle d'erreur par défaut est généralement utilisée pour renvoyer un message d'erreur générique pour toute erreur inattendue, tel qu'un message contenant les coordonnées de l'assistance technique. Cette réponse par défaut sert à la fois à fournir des informations conviviales aux développeurs tout en masquant les URL de backend ou d'autres informations susceptibles d'être utilisées pour compromettre le système.

Par exemple, vous définissez la stratégie AssignMessage suivante pour renvoyer une erreur générique :

<AssignMessage name="AM-Return-Generic-Error">
  <Set>
    <Payload type="text/plain">SERVICE UNAVAILABLE. PLEASE CONTACT SUPPORT: support@company.com.</Payload>
  </Set>
</AssignMessage>

Incluez l'élément <AlwaysEnforce> dans le tag <DefaultFaultRule> pour exécuter la règle d'erreur par défaut pour chaque erreur, même si une autre règle d'erreur a déjà été exécutée. La règle d'erreur par défaut est toujours la dernière règle d'erreur à s'exécuter :

  <DefaultFaultRule name="fault-rule">
    <Step>
      <Name>AM-Return-Generic-Error</Name>
    </Step>
    <AlwaysEnforce>true</AlwaysEnforce>
  </DefaultFaultRule>

L'une des utilisations de la règle DefaultFaultRule consiste à déterminer le type d'erreur qui se produit lorsque vous ne pouvez pas l'identifier autrement. Par exemple, si votre proxy d'API échoue en raison d'une erreur que vous ne pouvez pas déterminer, vous pouvez utiliser la règle d'erreur par défaut pour appeler la règle AssignMessage suivante. Cette règle écrit la valeur fault.name dans un en-tête nommé Unhandled-Fault dans la réponse :

<AssignMessage name="AM-Set-Fault-Header">
  <Set>
    <Headers>
      <Header name="Unhandled-Fault">{fault.name}</Header>
    </Headers>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

Vous pouvez alors afficher l'en-tête dans l'outil Debug ou dans la réponse pour voir la cause de l'erreur.

Ajout de la journalisation des messages à PostClientFlow

PostClientFlow est le seul flux qui s'exécute une fois que le proxy passe l'état d'erreur. Seule la règle MessageLogging peut être associée à ce flux. Elle est exécutée une fois la réponse renvoyée au client. Bien que l'association de la règle MessageLogging à ce flux ne relève techniquement pas du traitement des erreurs, vous pouvez l'utiliser pour consigner des informations en cas d'erreur. Comme il est exécuté, que le proxy ait réussi ou échoué, vous pouvez placer les règles MessageLogging dans PostClientFlow et être sûr qu'elles s'exécutent toujours.

Gérer les erreurs de stratégie dans le flux actuel

Les exemples présentés jusqu'à présent utilisent tous une règle d'erreur sur ProxyEndpoint ou TargetEndpoint pour gérer les erreurs de stratégie dans le cadre de l'état d'erreur. En effet, la valeur par défaut de l'élément continueOnError d'une stratégie est false, ce qui signifie que lorsqu'une erreur se produit dans une stratégie, le contrôle est dirigé vers l'état d'erreur. Une fois dans l'état de serreur, vous ne pouvez pas retourner le contrôle au pipeline normal et vous renvoyez généralement une forme de message d'erreur à l'application appelante.

Toutefois, si vous définissez l'élément continueOnError sur true pour une stratégie, le contrôle reste dans le flux en cours et la stratégie suivante du pipeline s'exécute une fois que la stratégie a provoqué l'erreur. L'avantage de gérer l'erreur dans le flux actuel est que vous avez peut-être un moyen de vous remettre de l'erreur pour terminer le traitement de la requête.

Voici, ci-dessous, une stratégie VerifyAPIKey nommée verify-api-key, avec l'élément continueOnError défini sur true:

<VerifyAPIKey continueOnError="true" name="verify-api-key">
  <DisplayName>Verify API Key</DisplayName>
  <APIKey ref="request.queryparam.apikey"/>
</VerifyAPIKey>

Si la clé API est manquante ou non valide, la règle VerifyAPIKey définit la variable oauthV2.verify-api-key.failed sur true, mais le traitement se poursuit dans le flux en cours.

Vous ajoutez ensuite la stratégie VerifyAPIKey en tant qu'étape dans le pré-flux de ProxyEndpoint :

<ProxyEndpoint name="default">
  ...
  <PreFlow name="PreFlow">
    <Request>
      <Step>
        <Name>verify-api-key</Name>
      </Step>
      <Step>
        <Name>FaultInFlow</Name>
        <Condition>oauthV2.verify-api-key.failed = "true"</Condition>
      </Step>
    </Request>
    <Response/>
  </PreFlow>
</ProxyEndpoint>

Notez que l'étape suivante de PreFlow utilise une condition servant à tester l'existence d'une erreur. Si une erreur s'est produite dans la règle VerifyAPIKey, la règle nommée FaultInFlow s'exécute. Sinon, la règle FaultInFlow est ignorée. La règle FaultInFlow peut effectuer de nombreuses actions, telles que consigner l'erreur, tenter de la corriger ou effectuer toute autre action.

Déclencher une erreur à l'aide de la règle RaiseFault

Vous pouvez utiliser la règle RaiseFault à tout moment dans un flux pour déclencher une erreur. Lorsqu'une règle RaiseFault s'exécute, elle interrompt le flux en cours et transfère le contrôle à l'état d'erreur.

L'une des utilisateurs de la règle RaiseFault consiste à tester une condition spécifique qu'une autre règle pourrait ne pas détecter. Dans l'exemple ci-dessus, vous avez ajouté un tag <Condition> à un tag PreFlow <Step>, ce qui a entraîné l'exécution de la règle FaultInFlow si la condition est remplie. Si FaultInFlow est une règle RaiseFault, vous pouvez contrôler le transfert vers l'état d'erreur. Vous pouvez également insérer une règle RaiseFault dans un flux afin de déboguer et tester vos règles FaultRules.

Lorsqu'une stratégie RaiseFault déclenche une erreur, vous pouvez utiliser la règle d'erreur et la condition suivantes pour la traiter :

<FaultRule name="raisefault_rule">
  <Step>
    <Name>POLICY-NAME-HERE</Name>
  </Step>
  <Condition>fault.name = "RaiseFault"</Condition>
</FaultRule>

Notez que la condition teste une erreur nommée RaiseFault. La règle RaiseFault définit toujours la valeur de fault.name sur RaiseFault. Vous pouvez également définir des variables personnalisées dans une règle RaiseFault. Le cas échéant, vous pouvez alors tester ces variables dans les éléments de condition.

Gestion personnalisée des codes d'erreur HTTP du serveur cible

Les exemples présentés dans les sections précédentes s'appliquent aux erreurs créées par les règles. Toutefois, vous pouvez également créer une réponse personnalisée pour les erreurs de niveau transport, ce qui signifie que les erreurs HTTP sont renvoyées par le serveur cible. Pour contrôler la réponse à partir d'une erreur HTTP, configurez un TargetEndpoint pour traiter les codes de réponse HTTP.

Par défaut, Apigee traite les codes de réponse HTTP dans la plage 1xx-3xx comme des réussites, et les codes de réponse HTTP de la plage 4xx-5xx comme des échecs. Cela signifie que toute réponse du service de backend ayant un code de réponse HTTP 4xx-5xx appelle automatiquement l'état d'erreur, qui renvoie alors un message d'erreur directement au client demandeur.

Vous pouvez créer des gestionnaires personnalisés pour tous les codes de réponse HTTP. Par exemple, vous ne souhaitez peut-être pas traiter tous les codes de réponse HTTP de la plage 4xx-5xx comme des "échecs", mais seulement 5xx, ou vous voulez renvoyer des messages d'erreur personnalisés pour les codes de réponse HTTP 400 et 500.

Dans l'exemple suivant, vous utilisez la propriété success.codes pour configurer le TargetEndpoint pour traiter les codes de réponse HTTP 400 et 500 en cas de réussite, ainsi que les codes HTTP par défaut. En traitant ces codes comme une réussite, le TargetEndpoint prend le relais du traitement du message de réponse, au lieu d'appeler l'état d'erreur :

<TargetEndpoint name="default">
  ...
  <HTTPTargetConnection>
    <Properties>
          <Property name="success.codes">1xx,2xx,3xx,400,500</Property>
    </Properties>
    <URL>http://weather.yahooapis.com</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

Comme vous pouvez le voir dans cet exemple, vous pouvez utiliser des caractères génériques pour définir la propriété success.codes sur une plage de valeurs.

La définition de la propriété success.codes écrase les valeurs par défaut. Par conséquent, si vous souhaitez ajouter le code HTTP 400 à la liste des codes de réussite par défaut, définissez cette propriété comme suit :

<Property name="success.codes">1xx,2xx,3xx,400</Property>

Toutefois, si vous souhaitez uniquement que le code HTTP 400 soit traité comme un code de réussite, définissez la propriété comme suit :

<Property name="success.codes">400</Property>

Vous pouvez maintenant définir des gestionnaires personnalisés pour les codes de réponse HTTP 400 et 500 afin de renvoyer un message de réponse personnalisé à l'application à l'origine de la requête. Le TargetEndpoint suivant utilise la règle nommée ReturnError pour gérer les codes de réponse HTTP 400 et 500 :

<TargetEndpoint name="default">
  <PreFlow name="PreFlow">
    <Request/>
    <Response>
      <Step>
        <Name>ReturnError</Name>
        <Condition>(response.status.code = 400) or (response.status.code = 500)</Condition>
      </Step>
    </Response>
  </PreFlow>

  <HTTPTargetConnection>
    <Properties>
      <Property name="success.codes">1xx,2xx,3xx,400,500</Property>
    </Properties>
    <URL>http://weather.yahooapis.com</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

Cette configuration TargetEndpoint amène la règle appelée ReturnError à gérer la réponse chaque fois que le TargetEndpoint rencontre un code de réponse HTTP 400 ou 500.

Classification des défaillances

Les services d'API regroupent les erreurs dans les catégories et sous-catégories suivantes.

Category Sous-catégorie Nom de l'erreur Description
Messaging Échecs qui se produisent pendant le flux de messages (échec de stratégie non inclus)
Erreurs personnalisées {fault_name} Toutes les erreurs explicitement gérées par le proxy d'API à l'aide de la stratégie RaiseFault
Codes de réponse InternalServerError, NotFound Codes d'erreur HTTP 5xx, 4xx
Échecs de routage NoRoutesMatched Échec de la sélection d'un TargetEndpoint nommé pour une requête
Échecs de classification NotFound Échecs provoqués par un URI de requête qui ne correspond à aucun BasePath pour des configurations ProxyEndpoint (c'est-à-dire qu'aucun proxy d'API ne correspond à l'URL dans la requête de l'application cliente)
Transport Erreurs au niveau du transport HTTP
Connectivité ConnectionRefused, ConnectionReset, ConnectionTimeout Échecs lors de l'établissement de connexions au niveau du réseau ou du transport
Validations des requêtes ContentLengthMissing, HostHeaderMissing Des erreurs se produisent lors des vérifications sémantiques de chaque requête
Validations des réponses Des erreurs se produisent lors des vérifications sémantiques de chaque réponse
Erreurs d'E/S SSLHandshakeError, ReadTimeout, ReadError, WriteTimeout, WriteError, ChunkError Erreurs de lecture/écriture sur les points de terminaison client ou cibles, les délais avant expiration, les erreurs TLS/SSL et les erreurs fragmentées
Système Erreurs d'exécution non définies
Mémoire OutOfMemory, GCOverLimit Défaillances liées à la mémoire
Thread RogueTaskTerminated Échecs tels que l'arrêt de tâches sur lesquelles le contrôle est perdu
Règle Les erreurs pour chaque type de règle sont définies dans la documentation de référence sur les règles.

Une erreur est toujours accompagnée d'une description textuelle du motif de l'échec. Lorsque le système génère une erreur, un ensemble d'attributs sont renseignés pour vous aider au dépannage. Un échec inclut les informations suivantes :

  • Motif
  • Attributs personnalisés définis par l'utilisateur