Obsługa awarii

Wyświetlasz dokumentację Apigee Edge.
Zapoznaj się z dokumentacją Apigee X. info

Podczas obsługiwania żądań z aplikacji przez serwery proxy interfejsu API może wystąpić wiele błędów. Na przykład serwery proxy interfejsu API mogą napotkać problemy z siecią podczas komunikacji z usługami backendu, aplikacje mogą przedstawiać wygasłe dane logowania, komunikaty żądań mogą być nieprawidłowo sformatowane itp.

Gdy po wywołaniu przez aplikację kliencką serwera proxy interfejsu API wystąpi błąd, do klienta zostanie zwrócony komunikat o błędzie. Domyślnie klient otrzymuje często niejasny komunikat o błędzie bez szczegółów ani wskazówek. Jeśli jednak chcesz zastąpić domyślne komunikaty o błędach bardziej przydatnymi komunikatami niestandardowymi, a nawet wzbogacić je o dodatkowe nagłówki HTTP, musisz skonfigurować w Edge niestandardową obsługę błędów.

Niestandardowa obsługa błędów umożliwia też dodawanie funkcji, takich jak rejestrowanie wiadomości za każdym razem, gdy wystąpi błąd.

Zanim omówimy wdrażanie niestandardowej obsługi błędów w proxy interfejsu API, warto zrozumieć, jak występują błędy i jak proxy interfejsu API na nie reagują.

Filmy

Aby dowiedzieć się więcej o obsłudze błędów, obejrzyj poniższe filmy.

Wideo Opis
Wprowadzenie do obsługi błędów i ścieżek błędów Dowiedz się więcej o obsłudze błędów i o tym, co się dzieje, gdy w proxy interfejsu API wystąpi błąd.
Obsługa błędów za pomocą reguł błędów Dowiedz się, jak obsługiwać błędy za pomocą reguł błędów.
Zgłaszanie błędów niestandardowych za pomocą zasady RaiseFault Podczas działania interfejsu API zgłaszaj niestandardowe błędy za pomocą zasady RaiseFault.
Definiowanie reguł błędów w proxy interfejsu API i docelowych punktach końcowych Zdefiniuj reguły błędów w proxy interfejsu API i docelowych punktach końcowych oraz poznaj różnice między nimi.
Omówienie kolejności wykonywania reguł błędów Poznaj kolejność wykonywania reguł błędów w proxy interfejsu API i docelowych punktach końcowych.
Definiowanie domyślnej reguły błędu Zdefiniuj domyślną regułę błędu, która będzie obsługiwać ogólne błędy w interfejsie API.

Jak występują błędy

Najpierw omówimy jak powstają błędy. Znajomość przyczyn występowania błędów pomaga planować różne sytuacje, w których chcesz wdrożyć niestandardową obsługę błędów.

Błędy automatyczne

Serwer proxy interfejsu API automatycznie zgłasza błąd w tych sytuacjach:

  • Zasada zwraca błąd. Jeśli na przykład wywołanie interfejsu API wysyła wygasły klucz, zasada VerifyAPIKey automatycznie zgłasza błąd. Jeśli liczba wywołań interfejsu API przekracza określony limit, błąd zgłasza zasada Quota lub zasada SpikeArrest. (Więcej informacji o rodzajach błędów, które mogą zgłaszać zasady, znajdziesz w dokumentacji błędów zasad).
  • W przepływie wiadomości serwera proxy interfejsu API wystąpił problem, np. błąd routingu.
  • Wystąpił błąd backendu, np. błąd HTTP spowodowany błędami na poziomie protokołu, błędami TLS/SSL lub niedostępnością usługi docelowej.
  • Wystąpiła awaria na poziomie systemu, np. wyjątek braku pamięci.

Więcej informacji o tych błędach znajdziesz w sekcji Taksonomia błędów w tym artykule.

Błędy niestandardowe

W sytuacjach, w których nie występuje automatyczny błąd, możesz zgłosić błąd niestandardowy, np. jeśli odpowiedź zawiera słowo „niedostępny” lub jeśli kod stanu HTTP jest większy niż 201. Aby to zrobić, dodaj zasadę RaiseFault w odpowiednim miejscu w przepływie proxy interfejsu API.

Zasady RaiseFault możesz dodać do przepływu proxy interfejsu API w taki sam sposób jak inne zasady. W poniższym przykładzie konfiguracji serwera proxy zasada Raise-Fault-1 jest dołączona do odpowiedzi TargetEndpoint. Jeśli w odpowiedzi z usługi docelowej występuje słowo „unavailable”, wykonywana jest zasada RaiseFault i zgłaszany jest błąd.

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

Chodzi tylko o to, aby pokazać, że możesz zgłaszać błędy niestandardowe. Więcej informacji o zasadach RaiseFault znajdziesz w sekcji FaultRules a zasady RaiseFault.

Więcej przykładów znajdziesz w tych postach na forum społeczności Apigee:

Działanie proxy interfejsu API w przypadku wystąpienia błędów

Co się dzieje, gdy serwer proxy zgłosi błąd.

Zamykanie potoku serwera proxy

Gdy serwer proxy interfejsu API napotka błąd, niezależnie od tego, jak do niego doszło, opuszcza normalny potok przepływu, przechodzi w stan błędu i zwraca komunikat o błędzie do aplikacji klienckiej. Gdy serwer proxy interfejsu API przejdzie w stan błędu, nie może przywrócić przetwarzania do normalnego potoku przepływu.

Załóżmy na przykład, że w żądaniu ProxyEndpoint serwera proxy API zasady są ułożone w tej kolejności:

  1. Weryfikacja klucza interfejsu API
  2. Limit
  3. JSON do XML

Jeśli podczas weryfikacji klucza interfejsu API wystąpi błąd, serwer proxy interfejsu API przejdzie w stan błędu. Zasady dotyczące limitu i przekształcania formatu JSON na XML nie są wykonywane, serwer proxy nie przechodzi do TargetEndpoint i do aplikacji klienckiej jest zwracany komunikat o błędzie.

Sprawdzanie reguł FaultRules

W stanie błędu proxy interfejsów API sprawdzają też (w podanej kolejności) obecność tych elementów w konfiguracji proxy interfejsu API, zanim zwrócą domyślny komunikat o błędzie do aplikacji klienckiej:

  1. Sekcja <FaultRules>, która zawiera logikę wywoływania niestandardowych komunikatów o błędach (i innych zasad) na podstawie określonych warunków zdefiniowanych przez Ciebie.
  2. Sekcja <DefaultFaultRule>, która w tych sytuacjach wywołuje domyślny komunikat o błędzie:
    • Nie zdefiniowano żadnych <FaultRules>.
    • Żadne istniejące <FaultRules> nie zostaną wykonane.
    • Element <AlwaysEnforce> ma wartość „true”.

W zasadzie serwer proxy interfejsu API umożliwia zwrócenie niestandardowego komunikatu o błędzie i wywołanie innej logiki. Jeśli serwer proxy nie znajdzie żadnej z tych sekcji lub jeśli istnieją, ale nie wywołały niestandardowego błędu, wyśle własny domyślny komunikat wygenerowany przez Edge.

Przykład prostej obsługi błędów

Zacznijmy od prostego przykładu, w którym wywołanie serwera proxy interfejsu API nie zawiera wymaganego klucza interfejsu API. Domyślnie do aplikacji klienckiej zwracana jest ta odpowiedź:

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"}}}

Użytkownicy interfejsu API mogą zrozumieć komunikat o błędzie, ale nie muszą. Wiele domyślnych błędów jest bardziej subtelnych i trudniejszych do odczytania.

Jako deweloper interfejsu API musisz zmienić ten komunikat, aby spełniał potrzeby osób, które ostatecznie go otrzymają, niezależnie od tego, czy jest to deweloper aplikacji na iOS, czy wewnętrzna grupa testowa, która ma własne wymagania dotyczące formatu komunikatu o błędzie.

Oto podstawowy przykład tworzenia niestandardowego komunikatu o błędzie, który będzie obsługiwać ten błąd. Wymaga to 1) zasad, które definiują niestandardowy komunikat, oraz 2) reguły FaultRule, która wykonuje zasady, gdy serwer proxy przechodzi w stan błędu.

1. Utwórz zasadę, która definiuje niestandardową wiadomość.

Najpierw utwórz zasadę, która definiuje niestandardowy komunikat o błędzie. Możesz użyć dowolnego typu zasady, np. zasady AssignMessage, która może ustawić ładunek i opcjonalne nagłówki HTTP, takie jak kod stanu i fraza przyczyny. Funkcja Przypisz wiadomość jest do tego idealna. Umożliwia kontrolowanie ładunku wiadomości, ustawianie innego kodu stanu HTTP, ustawianie innego tekstu uzasadnienia HTTP i dodawanie nagłówków HTTP.

Nie dołączaj zasad do żadnego przepływu w serwerze proxy interfejsu API. Wystarczy, że istnieje w pakiecie proxy. Aby to zrobić w edytorze proxy interfejsu zarządzania, otwórz kartę Develop (Tworzenie), a następnie w panelu Navigation (Nawigacja) kliknij ikonę + na pasku Policies (Zasady).

Umożliwia to utworzenie zasady bez dołączania jej do przepływu w proxy interfejsu API. Zasady, które nie są dołączone do żadnego przepływu, są oznaczone ikoną „odłączone” na liście zasad, jak pokazano obok zasady dotyczącej wiadomości z kluczem interfejsu API na poprzednim rysunku.

Poniżej znajduje się przykład zasady AssignMessage, która:

  • Zwraca komunikat JSON.
  • Ustawia kod stanu HTTP (911, czyli oczywisty nieistniejący kod stanu, aby zilustrować elastyczność, jaką masz). Kod stanu jest widoczny w nagłówku HTTP.
  • Ustawia frazę uzasadnienia HTTP (zastępuje domyślną frazę „Unauthorized” w przypadku tego błędu braku klucza API). Wyrażenie opisujące przyczynę pojawia się obok kodu stanu w nagłówku HTTP.
  • Tworzy i wypełnia nowy nagłówek HTTP o nazwie 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>
        <ReasonPhrase>Rejected by API Key Emergency Services</ReasonPhrase>
    </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>

Gdy ta zasada zostanie wykonana, odpowiedź dla aplikacji klienckiej będzie wyglądać tak: Porównaj ją z domyślną odpowiedzią wyświetlaną wcześniej.

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."}

To trochę głupie, ale pokazuje, co jest możliwe. Dzięki temu deweloper otrzymujący wiadomość wie, że zapomniał dołączyć klucz interfejsu API jako parametr zapytania.

Jak ta zasada jest egzekwowana? Dowiesz się tego z następnej sekcji.

2. Utwórz element <FaultRule>, który będzie wywoływać zasadę.

W sekcjach <ProxyEndpoint> lub <TargetEndpoint> konfiguracji serwera proxy dodasz <FaultRules> blok XML, który zawiera co najmniej 1 sekcję <FaultRule>. Każda reguła FaultRule reprezentuje inny błąd, który chcesz obsłużyć. W tym prostym przykładzie użyjemy tylko jednej reguły FaultRule, aby pokazać, z czego się składa.

Warto też dodać element <DefaultFaultRule>, aby w przypadku niewykonania żadnej z reguł FaultRule wyświetlać niestandardowy ogólny komunikat o błędzie.

Przykład

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

Najważniejsze kwestie:

  • Reguły FaultRules są zdefiniowane w punkcie końcowym serwera proxy. To ważne. Więcej informacji o umieszczaniu elementów FaultRules w elementach ProxyEndpoint i TargetEndpoint znajdziesz w dalszej części tego artykułu.
  • <Name> – nazwa zasady do wykonania. Nazwa pochodzi z atrybutu name zasady w elemencie nadrzędnym, jak pokazano w przykładzie zasady powyżej.
  • <Condition> – Edge analizuje warunek i wykonuje zasadę tylko wtedy, gdy warunek jest spełniony. Jeśli istnieje kilka reguł FaultRule, które zwracają wartość „prawda”, Edge wykonuje pierwszą z nich. (Ważne: kolejność, w jakiej są oceniane reguły FaultRule – od góry do dołu lub od dołu do góry – różni się w przypadku TargetEndpoint i ProxyEndpoint, co opisano w sekcji Wiele reguł FaultRule i logika wykonywania). Jeśli nie podasz warunku, reguła FaultRule będzie automatycznie przyjmować wartość true. Nie jest to jednak zalecane. Każda reguła FaultRule powinna mieć własny warunek.

  • <DefaultFaultRule> – jeśli nie zostanie wykonana żadna niestandardowa reguła FaultRule, zostanie wykonana reguła <DefaultFaultRule>, która wyśle bardziej ogólną wiadomość niestandardową zamiast tajemniczej domyślnej wiadomości wygenerowanej przez Edge. <DefaultFaultRule> może też mieć <Condition>, ale w większości przypadków nie będziesz go uwzględniać, ponieważ chcesz, aby był wykonywany w każdej sytuacji jako ostatnia deska ratunku.

    Reguła DefaultFaultRule jest zwykle używana do zwracania ogólnego komunikatu o błędzie w przypadku nieoczekiwanego błędu. Przykładem może być wiadomość zawierająca informacje kontaktowe zespołu pomocy technicznej. Ta domyślna odpowiedź ma podwójne zastosowanie: dostarcza deweloperom przydatnych informacji, a jednocześnie zaciera adresy URL backendu lub inne informacje, które mogłyby zostać wykorzystane do naruszenia bezpieczeństwa systemu.

Wiele reguł FaultRule i logika wykonywania

W sekcji Przykład prostego obsługiwania błędów użyliśmy prostego przykładu pojedynczej reguły FaultRule i warunku. W prawdziwym projekcie interfejsu API, w którym mogą wystąpić różne błędy, prawdopodobnie będziesz mieć wiele reguł FaultRule i regułę DefaultFaultRule w sekcjach <ProxyEndpoint><TargetEndpoint>. Ostatecznie jednak, gdy serwer proxy interfejsu API przechodzi w stan błędu, wykonywana jest tylko jedna reguła FaultRule.

W tej sekcji opisano logikę, której Edge używa do obsługi reguł FaultRule, od sposobu, w jaki wybiera jedną regułę FaultRule do wykonania, po sposób obsługi „wewnętrznych” warunków kroku, gdy zostanie wywołana ich reguła FaultRule. W tej sekcji znajdziesz też wskazówki dotyczące tego, kiedy należy definiować FaultRules w <ProxyEndpoint>, a kiedy w <TargetEndpoint>, oraz opis relacji między FaultRules a zasadą RaiseFault.

Wykonanie FaultRules

Oto logika, której Edge używa, gdy serwer proxy interfejsu API przechodzi w stan błędu. Pamiętaj, że ocena FaultRules w ProxyEndpoint i TargetEndpoint nieco się różni.

  1. Edge ocenia reguły FaultRules w punkcie ProxyEndpoint lub TargetEndpoint w zależności od tego, gdzie wystąpił błąd:
    • ProxyEndpoint – Edge zaczyna od najniższego poziomu w pliku XML konfiguracji i przechodzi w górę, oceniając <Condition> każdego <FaultRule> (warunek „zewnętrzny”, a nie „wewnętrzne” warunki <Step>).<FaultRule>
    • TargetEndpoint – Edge zaczyna od góry <FaultRule> w konfiguracyjnym pliku XML i przechodzi w dół, oceniając <Condition> każdego <FaultRule> (warunek „zewnętrzny”, a nie warunki „wewnętrzne” <Step>).
  2. Wykonuje pierwszą regułę FaultRule, której warunek jest prawdziwy. Jeśli element FaultRule nie ma warunku, domyślnie ma wartość „prawda”.
    • Gdy wykonywana jest reguła FaultRule, wszystkie kroki w niej są oceniane w kolejności od góry do dołu w konfiguracji XML. Kroki bez warunków są wykonywane automatycznie (zasady są wykonywane), a kroki z warunkiem <Condition>, który ma wartość „prawda”, są wykonywane (warunki, które mają wartość „fałsz”, nie są wykonywane).
    • Jeśli reguła FaultRule zostanie wykonana, ale żadne kroki w niej nie zostaną wykonane (ponieważ ich warunki mają wartość „false”), do aplikacji klienckiej zostanie zwrócony domyślny komunikat o błędzie wygenerowany przez Edge. Obiekt <DefaultFaultRule> nie zostanie wykonany, ponieważ Edge wykonał już jedną regułę FaultRule.

  3. Jeśli nie zostanie wykonana żadna reguła FaultRule, Edge wykona element <DefaultFaultRule>, jeśli jest obecny.

Poniżej znajdziesz przykłady z komentarzami w tekście.

Wykonywanie ProxyEndpoint

Ocena reguł FaultRule w punkcie ProxyEndpoint odbywa się od dołu do góry, więc zacznij od ostatniej reguły FaultRule w poniższym przykładzie i przechodź w górę. Na końcu sprawdź DefaultFaultRule.

<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), Edge
     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, Edge looks at this FaultRule
     first. But let's say this FaultRule is FALSE. A policy did not
     throw a FailedToResolveAPIKey error. Edge 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 Edge has already
     executed its one FaultRule). -->
    <DefaultFaultRule name="default-fault">
        <Step>
            <Name>Default-message</Name>
        </Step>
    </DefaultFaultRule>

Wykonanie TargetEndpoint

Ocena reguł FaultRule w obiekcie TargetEndpoint odbywa się od góry do dołu, więc zacznij od pierwszej reguły FaultRule w poniższym przykładzie i przechodź w dół. Na końcu sprawdź DefaultFaultRule.

<TargetEndpoint name="default">
...
    <FaultRules>
<!-- 1. Because this is the TargetEndpoint, Edge looks at this FaultRule
     first. Let's say this FaultRule is FALSE.
     A policy did not throw a FailedToResolveAPIKey error.
     Edge 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), Edge
     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 Edge has already
     executed its one FaultRule). -->
    <DefaultFaultRule name="default-fault">
        <Step>
            <Name>Default-message</Name>
        </Step>
    </DefaultFaultRule>

Kolejność reguł błędów

Jak widać w poprzednim przykładzie, kolejność umieszczania reguł FaultRule jest ważna w zależności od tego, czy błąd występuje w punkcie ProxyEndpoint czy TargetEndpoint.

Na przykład:

Kolejność ProxyEndpoint Kolejność TargetEndpoint

W tym przykładzie, ponieważ ocena jest przeprowadzana od dołu do góry, wykonywana jest reguła FaultRule 3, co oznacza, że reguły FaultRule 2 i 1 nie są oceniane.

5. FaultRule 1: FALSE

4. FaultRule 2: TRUE

3. FaultRule 3: TRUE

2. FaultRule 4: FALSE

1. FaultRule: 5 FALSE

W tym przykładzie, ponieważ ocena jest przeprowadzana od góry do dołu, wykonywana jest reguła FaultRule 2, co oznacza, że reguły FaultRule 3, 4 i 5 nie są oceniane.

1. FaultRule 1: FALSE

2. FaultRule 2: TRUE

3. FaultRule 3: TRUE

4. FaultRule 4: FALSE

5. FaultRule: 5 FALSE

Zasady do uwzględnienia

Wszystkie zasady z elementu FaultRule możesz wykonać, umieszczając je w elementach Steps. Możesz na przykład wykonać zasady AssignMessage, aby sformatować odpowiedź dla aplikacji klienta, a następnie zarejestrować wiadomość za pomocą zasad MessageLogging. Zasady są wykonywane w kolejności, w jakiej zostały umieszczone (od góry do dołu w pliku XML).

Reguły błędów są wywoływane TYLKO w stanie błędu (informacje o continueOnError)

Nagłówek może sugerować, że się powtarzamy, ale jest jeden szczególny niuans, o którym warto pamiętać w związku z błędem serwera proxy powodującym przejście serwera proxy interfejsu API w stan błędu – a raczej nieprzejście w stan błędu: atrybut continueOnError w zasadach.

Podsumowując: serwer proxy interfejsu API analizuje warunki <FaultRules><DefaultFaultRule> tylko wtedy, gdy przejdzie w stan błędu. Oznacza to, że nawet jeśli warunek FaultRule przyjmie wartość true, nie zostanie on wywołany, jeśli serwer proxy nie jest w stanie błędu.

Oto jednak przykład wystąpienia błędu, w którym serwer proxy nie przechodzi w stan błędu. W przypadku dowolnej zasady możesz ustawić atrybut w elemencie nadrzędnym o nazwie continueOnError. Ten atrybut jest bardzo ważny w przypadku obsługi błędów, ponieważ określa, czy w przypadku niepowodzenia zasady serwer proxy przechodzi w stan błędu. W większości przypadków warto zachować domyślne ustawienie continueOnError="false", które powoduje przejście serwera proxy w stan błędu, jeśli zasady nie zostaną spełnione, i wywołanie niestandardowej obsługi błędów. Jeśli jednak continueOnError="true" (np. nie chcesz, aby nieudane wywołanie usługi zatrzymywało wykonywanie proxy), w przypadku niepowodzenia tej zasady proxy nie przejdzie w stan błędu i nie będzie sprawdzać reguł FaultRules.

Informacje o rejestrowaniu błędów podczas continueOnError="true" znajdziesz w artykule Obsługa błędów zasad w bieżącym przepływie.

Gdzie zdefiniować reguły FaultRules: ProxyEndpoint lub TargetEndpoint

Gdy w proxy interfejsu API wystąpi błąd, może on dotyczyć <ProxyEndpoint> (żądanie z aplikacji klienckiej lub odpowiedź do niej) albo <TargetEndpoint> (żądanie do usługi docelowej lub odpowiedź z niej). W miejscu, w którym występuje ten błąd, Edge szuka reguł FaultRules.

Jeśli na przykład serwer docelowy jest niedostępny (kod stanu HTTP 503), serwer proxy interfejsu API przejdzie w stan błędu w odpowiedzi <TargetEndpoint>, a normalny przepływ serwera proxy interfejsu API nie będzie kontynuowany do <ProxyEndpoint>. Jeśli masz zdefiniowane reguły FaultRules tylko w <ProxyEndpoint>, nie będą one obsługiwać tego błędu.

Oto kolejny przykład. Jeśli zasada RaiseFault w odpowiedzi <ProxyEndpoint> wywoła błąd, reguła FaultRule w <TargetEndpoint> nie zostanie wykonana.

FaultRules a zasada RaiseFault

Reguły błędów i zasada RaiseFault mogą na pierwszy rzut oka wydawać się alternatywnymi sposobami obsługi błędów, co w pewnym sensie jest prawdą. Ale też współpracują. W tej sekcji wyjaśniamy, jak te 2 elementy są ze sobą powiązane. Zrozumienie tej zależności powinno pomóc Ci w projektowaniu obsługi błędów, zwłaszcza jeśli chcesz używać obu tych metod.

W skrócie:

  • Reguły błędów są zawsze oceniane, gdy serwer proxy interfejsu API przechodzi w stan błędu.
  • Zasada RaiseFault umożliwia wprowadzenie serwera proxy interfejsu API w stan błędu, gdy w innych okolicznościach błąd by nie wystąpił.

    Jeśli na przykład chcesz zgłosić błąd, gdy kod stanu HTTP w odpowiedzi z usługi docelowej jest większy niż 200, dodaj zasadę RaiseFault w przepływie odpowiedzi. Mogłoby to wyglądać następująco:

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

    Zasada RaiseFault wysyła też komunikat o błędzie do aplikacji klienckiej.

Co się stanie, gdy zasada RaiseFault wywoła błąd, który spowoduje przejście serwera proxy w stan błędu, co może spowodować wykonanie zasady FaultRule? W tym miejscu sytuacja może się nieco skomplikować. Jeśli zasada RaiseFault zwróci komunikat o błędzie i zostanie wywołana reguła FaultRule, która również zwróci komunikat o błędzie, co zostanie zwrócone do aplikacji klienckiej?

  • Ponieważ reguła FaultRule lub DefaultFaultRule jest wykonywana po zasadzie RaiseFault, dane odpowiedzi reguły FaultRule mają wyższy priorytet.
  • Dane odpowiedzi zasady RaiseFault (kod stanu, fraza przyczyny lub ładunek wiadomości) są używane, jeśli nie są ustawione przez FaultRule lub DefaultFaultRule.
  • Jeśli zarówno zasada RaiseFault, jak i FaultRule dodają niestandardowe nagłówki HTTP, oba są uwzględniane w odpowiedzi. Zduplikowane nazwy nagłówków tworzą nagłówek z wieloma wartościami.

Oto przykład tego, co jest ustawiane przez zasadę RaiseFault i FaultRule oraz co jest zwracane do aplikacji klienta. Przykłady są krótkie i nie odzwierciedlają sprawdzonych metod.

Aplikacja kliencka otrzymuje:

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

<- Fault rules policy sets this:

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

Ta zasada<- RaiseFault ustawia tę wartość:

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

Warunki dotyczące budynków

Warunki są kluczem do wykonania reguły FaultRule. Warunki FaultRule tworzy się w taki sam sposób jak inne warunki w Edge, np. warunki przepływów warunkowych lub warunki RaiseFault.

Aby umieścić resztę tej sekcji w kontekście, podajemy przykładową regułę błędu, która ma zewnętrzny warunek FaultRule i wewnętrzny warunek Step.

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

Zmienne związane z błędami zasad

Zmienne fault.name{policy_namespace}.{policy_name}.failed są dostępne, gdy zasada zgłosi błąd.

fault.name

Jeśli zasada nie działa, przechwyć błąd w warunku za pomocą zmiennej fault.name. Na przykład:

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

Nazwa błędu pojawi się w domyślnym komunikacie o błędzie. Na przykład w tym przypadku nazwa błędu to FailedToResolveAPIKey. W tym przypadku zmienna przepływu o nazwie fault.name ma wartość FailedToResolveAPIKey.

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

Warunek będzie wyglądał tak:

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

Listę błędów związanych z zasadami znajdziesz w tym artykule.

{policy_namespace}.{policy_name}.failed

Zmienna *.failed jest dostępna, gdy zasada nie zostanie spełniona. Poniżej znajdziesz przykłady zmiennych *.failed w przypadku różnych zasad. W przypadku przestrzeni nazw zasad zmienne przepływu znajdziesz w każdym temacie dokumentacji zasad.

Inne dostępne zmienne

Gdy serwer proxy interfejsu API przechodzi w stan błędu, jedynymi dostępnymi zmiennymi do użycia w warunkach są:

  • Zmienne zasady, które nie zostały spełnione.
  • Zmienne wiadomości HTTP, które istniały w momencie wystąpienia błędu. Jeśli na przykład w odpowiedzi wystąpi błąd, reguła FaultRule w <TargetEndpoint> może używać danych HTTP response.status.code, message.content, error.content itd. Jeśli nie powiodła się zasada dotycząca limitu, możesz użyć zmiennej ratelimit.{quota_policy_name}.exceed.count. Skorzystaj z narzędzia śledzeniatematów referencyjnych dotyczących zasad, aby dowiedzieć się, które zmienne i dane HTTP są dostępne.

Więcej informacji

Sprawdzone metody obsługi błędów

Obsługa błędów jest ważnym zadaniem projektowym w architekturze podczas tworzenia serwera proxy interfejsu API. Warto poświęcić czas na ustalenie, jak i kiedy będziesz obsługiwać błędy, jakie komunikaty o błędach będą wyświetlane oraz jak będą wyglądać. Po ustaleniu tych kwestii (lub w trakcie tego procesu) skorzystaj z tych sprawdzonych metod, aby wdrożyć obsługę błędów.

Oto kilka sprawdzonych metod projektowania i tworzenia obsługi błędów:

  • W przypadku każdej reguły FaultRule podaj „zewnętrzny” element <Condition> (równorzędny z elementem <Step>). Reguły błędów bez warunku zewnętrznego są automatycznie oceniane jako prawdziwe. Warunki kroku „wewnętrznego” nie są używane do określania, czy reguła FaultRule ma wartość prawda czy fałsz. Warunki kroku są oceniane dopiero po wykonaniu przez Edge reguły FaultRule, która je zawiera. W przypadku FaultRule zwykle występuje wiele kroków z zasadami Assign Message (lub innymi), z których każdy ma warunek kroku.
  • Aby obsługiwać błędy w wielu zasadach tego samego typu (np. w wielu zasadach Quota), utwórz po 1 regule FaultRule dla każdego błędu zasady, który prawdopodobnie otrzymasz. Na przykład utwórz regułę FaultRule dla każdego prawdopodobnego błędu w zasadach dotyczących limitów, np. QuotaViolation, InvalidMessageWeight, StartTimeNotSupported. (Błędy zasad znajdziesz w dokumentacji błędów zasad). Gdy odkryjesz dodatkowe błędy, które wymagają obsługi, możesz później wrócić i dodać je do reguł FaultRules. Możesz to robić iteracyjnie, ale wymaga to ponownego wdrożenia serwera proxy). Takie podejście pozwala wychwycić ten sam typ błędu niezależnie od tego, która zasada go zgłasza, co sprawia, że plik XML FaultRules jest wydajny.

    Jeśli potrzebujesz bardziej szczegółowej kontroli błędów, użyj warunków wewnętrznego kroku. Jeśli na przykład w przepływie żądań wymuszasz zarówno limit indywidualnego dewelopera, jak i limit globalny za pomocą 2 zasad, ustaw warunek „zewnętrznej” reguły FaultRule tak, aby był wywoływany w przypadku błędu QuotaViolation (który jest zgłaszany, gdy limit zostanie przekroczony w obu przypadkach). Następnie ustaw warunki kroku, aby ocenić zmienne exceed.count w obu zasadach dotyczących limitów. Do klienta jest wysyłany tylko odpowiedni błąd (przekroczenie limitu dewelopera lub przekroczenie limitu globalnego). Oto przykład takiej konfiguracji:

    <FaultRule name="over_quota">
    <!-- This condition catches a QuotaViolation in *any* Quota policy -->
      <Condition>(fault.name = "QuotaViolation")</Condition>
      <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>
    </FaultRule>

    Inny przykład znajdziesz w tym wątku na forum społeczności Apigee.

  • Aby obsługiwać błędy podczas korzystania z jednej zasady danego typu, rozważ użycie pojedynczej reguły błędu, która jest wykonywana, gdy ta zasada zawiedzie. Uwzględnij w niej wiele kroków, które odpowiadają każdemu możliwemu błędowi. Dzięki temu plik XML jest bardziej wydajny, ponieważ używa jednej reguły FaultRule zamiast wielu reguł (po jednej dla każdego typu błędu). Na przykład:

    <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>Generic-Key-Fault</Name>
      </Step>
      <Step>
        <Name>Assign-Message-Raise-Fault-1</Name>
        <Condition>(fault.name = "FailedToResolveAPIKey")</Condition>
      </Step>
      <Step>
        <Name>Assign-Message-Raise-Fault-2</Name>
        <Condition>(fault.name = "InvalidApiKey")</Condition>
      </Step>
    </FaultRule>
  • Dodaj elementy FaultRules w miejscach, w których wystąpią błędy (po stronie klienta <ProxyEndpoint> lub po stronie docelowej <TargetEndpoint>). Dodaj elementy FaultRules dla każdej zasady, która występuje w każdej lokalizacji.
  • W FaultRules możesz wykonać dowolny typ zasady, która może zwrócić komunikat do aplikacji klienta. Idealna do tego jest zasada AssignMessage. Jeśli chcesz śledzić błędy, możesz też zarejestrować komunikat za pomocą zasad MessageLogging.
  • Jeśli używasz zasad RaiseFault w połączeniu z zasadami FaultRules, skoordynuj dane odpowiedzi, które są odsyłane, gdy zarówno zasady RaiseFault, jak i zasady FaultRule zwracają dane. Jeśli na przykład zasady RaiseFault resetują kod stanu HTTP, nie używaj elementu FaultRule do resetowania kodu stanu. Najgorsze, co może się zdarzyć, to zwrócenie do aplikacji klienta domyślnego kodu stanu.
  • <DefaultFaultRule> wykonanie:
    • Jeśli chcesz, aby reguła <DefaultFaultRule> była zawsze wykonywana, gdy nie jest wykonywana żadna inna reguła FaultRule, nie umieszczaj w niej elementu <Condition>.
    • Jeśli chcesz, aby element <DefaultFaultRule> był zawsze wykonywany, nawet gdy została wykonana inna reguła FaultRule, dodaj element podrzędny <AlwaysEnforce>true</AlwaysEnforce>.

Wzór scentralizowanego, wielokrotnego użytku mechanizmu obsługi błędów

W tym poście na forum społeczności Apigee opisano wzorzec scentralizowanego obsługi błędów bez duplikowania kodu:

Wzorzec obsługi błędów w przypadku serwerów proxy Apigee

Tworzenie reguł FaultRules

Aby dodać element FaultRule, musisz edytować konfigurację XML elementu ProxyEndpoint lub TargetEndpoint. Możesz to zrobić w interfejsie Edge w panelu Kod widoku Programowanie w przypadku proxy interfejsu API lub edytować plik XML, który definiuje ProxyEndpoint lub TargetEndpoint.

Jeśli tworzysz reguły FaultRules w interfejsie zarządzania, najpierw utwórz zasady, które chcesz wykonać, a potem dodaj je do konfiguracji reguły FaultRule. (Jeśli spróbujesz zapisać regułę FaultRule, która odwołuje się do zasady, która nie została jeszcze utworzona, w interfejsie pojawi się błąd).

Dodawanie zasad do elementu FaultRule

W zasadzie FaultRule możesz umieścić dowolną zasadę, ale najczęściej używasz zasady AssignMessage, która generuje niestandardowy komunikat z odpowiedzią w przypadku wystąpienia błędu. Zasada AssignMessage umożliwia skonfigurowanie odpowiedzi HTTP z elementami ładunku, kodu stanu HTTP, nagłówków i frazy przyczyny.

Poniżej znajdziesz przykład typowej konfiguracji zasady AssignMessage:

<AssignMessage name="fault_invalidkey">
  <Set>
      <Payload contentType="text/plain">Contact support at support@mycompany.com.</Payload>
      <StatusCode>401</StatusCode>
      <ReasonPhrase>Unauthorized</ReasonPhrase>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

Teraz możesz używać tych zasad w regule FaultRule. Zwróć uwagę, jak w zasadzie FaultRule odwołujesz się do zasady AssignMessage według nazwy:

<ProxyEndpoint name="default">
  ...
  <FaultRules>
    <FaultRule name="invalid_key_rule">
      <Step>
        <Name>fault_invalidkey</Name>
      </Step>
      <Condition>(fault.name = "InvalidApiKey")</Condition>
    </FaultRule>
  </FaultRules>
</ProxyEndpoint>

Gdy wdrożysz powyższą konfigurację, serwer proxy interfejsu API będzie wykonywać zasadę AssignMessage o nazwie fault_invalidkey za każdym razem, gdy aplikacja przedstawi nieprawidłowy klucz interfejsu API.

W ramach elementu FaultRule możesz wykonać kilka zasad, jak pokazano w tym przykładzie:

<ProxyEndpoint name="default">
  ...
  <FaultRules>
    <FaultRule name="invalid_key_rule">
      <Step>
        <Name>policy1</Name>
      </Step>
      <Step>
        <Name>policy2</Name>
      </Step>
      <Step>
        <Name>policy3</Name>
      </Step>
      <Condition>(fault.name = "InvalidApiKey")</Condition>
    </FaultRule>
  </FaultRules>
</ProxyEndpoint>

Zasady są wykonywane w zdefiniowanej kolejności. Możesz na przykład użyć zasady MessageLogging, zasady ExtractVariables, zasady AssignMessage lub dowolnej innej zasady w ramach FaultRule. Pamiętaj, że przetwarzanie reguły FaultRule natychmiast się zatrzymuje, jeśli wystąpi jedna z tych sytuacji:

  • Każda zasada w FaultRule powoduje błąd.
  • Każda zasada w FaultRule jest typu RaiseFault.

Definiowanie niestandardowego komunikatu o błędzie zwracanego przez FaultRule

Zgodnie ze sprawdzonymi metodami należy definiować jasne odpowiedzi o błędach z interfejsów API. W ten sposób możesz przekazywać klientom spójne i przydatne informacje.

W tym przykładzie zasad AssignMessage użyto tagów <Payload>, <StatusCode><ReasonPhase> do zdefiniowania niestandardowej odpowiedzi o błędzie wysyłanej do klienta w przypadku błędu InvalidApiKey (patrz poprzedni przykład FaultRules).

<AssignMessage name="fault_invalidkey">
  <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>
    <ReasonPhrase>Unauthorized</ReasonPhrase>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

Odpowiedź zawiera:

  • Ładunek zawierający komunikat o błędzie i adres e-mail, pod który można się kontaktować z zespołem pomocy.
  • Kod stanu HTTP zwrócony w odpowiedzi.
  • Wyjaśnienie, czyli krótki opis błędu.

Tworzenie elementu DefaultFaultRule

Reguła DefaultFaultRule działa jako procedura obsługi wyjątków w przypadku każdego błędu, który nie jest jawnie obsługiwany przez inną regułę FaultRule. Jeśli warunki wszystkich reguł FaultRule nie pasują do błędu, błąd jest obsługiwany przez regułę DefaultFaultRule. Włącz domyślną obsługę błędów, dodając tag <DefaultFaultRule> jako element podrzędny elementu ProxyEndpoint lub TargetEndpoint.

Na przykład konfiguracja TargetEndpoint poniżej definiuje DefaultFaultRule, która wywołuje zasadę o nazwie ReturnGenericError:

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

  <DefaultFaultRule name="fault-rule">
    <Step>
      <Name>ReturnGenericError</Name>
    </Step>
  </DefaultFaultRule>

  <HTTPTargetConnection>
    <URL>http://mocktarget.apigee.net</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

Reguła DefaultFaultRule jest zwykle używana do zwracania ogólnego komunikatu o błędzie w przypadku nieoczekiwanego błędu, np. komunikatu zawierającego informacje kontaktowe do pomocy technicznej. Ta domyślna odpowiedź służy dwóm celom: dostarcza deweloperom przydatnych informacji, a jednocześnie zaciera adresy URL backendu lub inne informacje, które mogłyby zostać wykorzystane do naruszenia bezpieczeństwa systemu.

Na przykład możesz zdefiniować te zasady AssignMessage, aby zwracać ogólny błąd:

<AssignMessage name="ReturnGenericError">
  <Set>
    <Payload type="text/plain">SERVICE UNAVAILABLE. PLEASE CONTACT SUPPORT: support@company.com.</Payload>
  </Set>
</AssignMessage>

Umieść element <AlwaysEnforce> w tagu <DefaultFaultRule>, aby wykonywać regułę DefaultFaultRule w przypadku każdego błędu, nawet jeśli inna reguła FaultRule została już wykonana. Reguła DefaultFaultRule jest zawsze ostatnią regułą FaultRule, która jest wykonywana:

  <DefaultFaultRule name="fault-rule">
    <Step>
      <Name>ReturnGenericError</Name>
    </Step>
    <AlwaysEnforce>true</AlwaysEnforce>
  </DefaultFaultRule>

Jednym z zastosowań DefaultFaultRule jest określanie typu błędu, który występuje, gdy nie można go inaczej ustalić. Na przykład serwer proxy interfejsu API zwraca błąd, którego nie możesz określić. Użyj DefaultFaultRule, aby wywołać tę zasadę AssignMessage. Ta zasada zapisuje wartość fault.name w nagłówku o nazwie DefaultFaultHeader w odpowiedzi:

<AssignMessage async="false" continueOnError="false" enabled="true" name="DefaultFaultRule">
  <DisplayName>DefaultFaultRule</DisplayName>
  <Set>
    <Headers>
      <Header name="DefaultFaultHeader">{fault.name}</Header>
    </Headers>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
  <AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>

Następnie możesz wyświetlić nagłówek w narzędziu śledzenia Edge lub w odpowiedzi, aby sprawdzić, co spowodowało błąd.

Dodawanie rejestrowania wiadomości do PostClientFlow

PostClientFlow to jedyny przepływ, który jest wykonywany po przejściu serwera proxy w stan błędu. Do tego przepływu można dołączyć tylko zasady MessageLogging, które są wykonywane po wysłaniu odpowiedzi do klienta. Chociaż dołączanie zasady MessageLogging do tego przepływu nie jest technicznie obsługą błędów, możesz jej używać do rejestrowania informacji w przypadku wystąpienia błędu. Jest on wykonywany niezależnie od tego, czy serwer proxy działa prawidłowo, czy nie. Dlatego w sekcji PostClientFlow możesz umieścić zasady rejestrowania wiadomości i mieć pewność, że zawsze zostaną wykonane.

Obsługa błędów zasad w bieżącym przepływie

W pokazanych do tej pory przykładach do obsługi błędów zasad w ramach stanu błędu użyto elementu FaultRule w ProxyEndpoint lub TargetEndpoint. Dzieje się tak, ponieważ domyślna wartość elementu continueOnError w zasadach to false, co oznacza, że gdy w zasadach wystąpi błąd, sterowanie jest przekazywane do stanu błędu. Po przejściu w stan błędu nie możesz przywrócić kontroli do normalnego potoku. Zwykle zwracasz do aplikacji wywołującej komunikat o błędzie.

Jeśli jednak w przypadku zasady ustawisz element continueOnError na true, kontrola pozostanie w bieżącym przepływie, a następna zasada w potoku zostanie wykonana po zasadzie, która spowodowała błąd. Zaletą obsługi błędu w bieżącym przepływie jest to, że możesz mieć możliwość odzyskania danych po błędzie, aby dokończyć przetwarzanie żądania.

Poniżej znajduje się zasada VerifyAPIKey o nazwie verify-api-key, w której element continueOnError ma wartość true:.

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

Jeśli klucz interfejsu API jest nieprawidłowy lub go brakuje, zasada VerifyAPIKey ustawia zmienną oauthV2.verify-api-key.failed na wartość true, ale przetwarzanie jest kontynuowane w bieżącym przepływie.

Następnie dodaj zasadę VerifyAPIKey jako krok w PreFlow elementu 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>

Zwróć uwagę, że następny krok w PreFlow używa warunku do sprawdzenia, czy występuje błąd. Jeśli w zasadach VerifAPIKey wystąpił błąd, zostaną wykonane zasady o nazwie FaultInFlow. W innym przypadku FaultInFlow zasada jest pomijana. FaultInFlow zasady mogą wykonywać wiele czynności, np. rejestrować błąd, próbować go naprawić lub podejmować inne działania.

Wywoływanie błędu za pomocą zasady RaiseFault

W dowolnym momencie przepływu możesz użyć zasady RaiseFault, aby wywołać błąd. Gdy wykonuje się zasada RaiseFault, przerywa ona bieżący przepływ i przekazuje kontrolę do stanu błędu.

Jednym z zastosowań zasady RaiseFault jest testowanie określonego warunku, którego inna zasada może nie wykryć. W przykładzie powyżej dodano tag <Condition> do tagu <Step> PreFlow, co spowodowało wykonanie zasady FaultInFlow, jeśli warunek został spełniony. Jeśli FaultInFlow to zasada RaiseFault, sterowanie przechodzi do stanu błędu. Możesz też wstawić w przepływie zasadę RaiseFault, aby debugować i testować reguły błędów.

Gdy zasada RaiseFault wywoła błąd, możesz go przetworzyć za pomocą tej reguły FaultRule i tego warunku:

<FaultRule name="raisefault_rule">
  <Step>
    <Name>{policy_name}</Name>
  </Step>
  <Condition>(fault.name = "RaiseFault")</Condition>
</FaultRule>

Zwróć uwagę, że warunek testuje błąd o nazwie RaiseFault. Zasada RaiseFault zawsze ustawia wartość fault.name na RaiseFault.

Niestandardowa obsługa kodów błędów HTTP z serwera docelowego

Przykłady podane w poprzednich sekcjach dotyczą błędów spowodowanych przez zasady. Możesz też utworzyć niestandardową odpowiedź na błędy na poziomie transportu, czyli błędy HTTP zwracane przez serwer docelowy. Aby kontrolować odpowiedź na błąd HTTP, skonfiguruj element TargetEndpoint tak, aby przetwarzał kody odpowiedzi HTTP.

Domyślnie Edge traktuje kody odpowiedzi HTTP z zakresu 1xx–3xx jako „sukces”, a kody odpowiedzi HTTP z zakresu 4xx–5xx jako „błąd”. Oznacza to, że każda odpowiedź z usługi backendu z kodem odpowiedzi HTTP 4xx–5xx automatycznie wywołuje stan błędu, który następnie zwraca komunikat o błędzie bezpośrednio do klienta wysyłającego żądanie.

Możesz tworzyć niestandardowe procedury obsługi dla dowolnych kodów odpowiedzi HTTP. Możesz na przykład nie chcieć traktować wszystkich kodów odpowiedzi HTTP z zakresu 4xx–5xx jako „błędu”, a tylko kody 5xx. Możesz też chcieć zwracać niestandardowe komunikaty o błędach dla kodów odpowiedzi HTTP 400 i 500.

W następnym przykładzie użyjesz właściwości success.codes, aby skonfigurować TargetEndpoint tak, aby traktował kody odpowiedzi HTTP 400 i 500 jako udane, a także domyślne kody HTTP. Traktując te kody jako powodzenie, TargetEndpoint przejmuje przetwarzanie wiadomości z odpowiedzią zamiast wywoływać stan błędu:

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

Jak widać na tym przykładzie, możesz użyć symboli wieloznacznych, aby ustawić właściwość success.codes na zakres wartości.

Ustawienie właściwości success.codes zastępuje wartości domyślne. Jeśli więc chcesz dodać kod HTTP 400 do listy domyślnych kodów powodzenia, ustaw tę właściwość w ten sposób:

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

Jeśli jednak chcesz, aby tylko kod HTTP 400 był traktowany jako kod powodzenia, ustaw właściwość w ten sposób:

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

Możesz teraz zdefiniować niestandardowe moduły obsługi kodów odpowiedzi HTTP 400 i 500, aby zwracać dostosowany komunikat odpowiedzi do aplikacji wysyłającej żądanie. Ten element TargetEndpoint używa zasady o nazwie ReturnError do obsługi kodów odpowiedzi HTTP 400 i 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>

Ta konfiguracja TargetEndpoint powoduje, że zasada o nazwie ReturnError obsługuje odpowiedź, gdy TargetEndpoint napotka kod odpowiedzi HTTP 400 lub 500.

Taksonomia usterek

Usługi API dzielą błędy na te kategorie i podkategorie.

Kategoria Podkategoria Nazwa błędu Opis
Wiadomości Błędy, które występują podczas przepływu wiadomości (z wyjątkiem błędów zasad)
Błędy niestandardowe {fault_name} Wszelkie błędy, które są jawnie obsługiwane przez serwer proxy interfejsu API za pomocą zasady RaiseFault.
Kody odpowiedzi InternalServerError, NotFound Kody błędów HTTP 5xx, 4xx
Błędy routingu NoRoutesMatched Nie udało się wybrać nazwanego punktu końcowego TargetEndpoint dla żądania
Błędy klasyfikacji NotFound Błędy spowodowane przez identyfikator URI żądania, który nie pasuje do żadnego elementu BasePath w konfiguracjach ProxyEndpoint (czyli żaden serwer proxy interfejsu API nie pasuje do adresu URL w żądaniu aplikacji klienckiej).
Transport Błędy na poziomie transportu HTTP
Połączenia ConnectionRefused, ConnectionReset, ConnectionTimeout Błędy występują podczas nawiązywania połączeń sieciowych lub połączeń na poziomie transportu
Prośby o weryfikację ContentLengthMissing, HostHeaderMissing Błędy występują podczas sprawdzania semantyki każdego żądania
Weryfikacja odpowiedzi Błędy występują podczas sprawdzania semantyki w przypadku każdej odpowiedzi
Błędy wejścia/wyjścia SSLHandshakeError, ReadTimeout, ReadError, WriteTimeout, WriteError, ChunkError Błędy odczytu/zapisu w punktach końcowych klienta lub docelowych, przekroczenia limitu czasu, błędy TLS/SSL i błędy związane z przesyłaniem danych w blokach.
System Niezdefiniowane błędy czasu działania
Pamięć OutOfMemory, GCOverLimit Błędy związane z pamięcią
Wątek RogueTaskTerminated Błędy, takie jak zakończenie zadań, które wymknęły się spod kontroli
Zasady Błędy dotyczące każdego typu zasad są zdefiniowane w dokumentacji zasad.

Błąd zawsze jest opatrzony opisem tekstowym przyczyny niepowodzenia. Gdy system zgłosi błąd, wypełniany jest zestaw atrybutów, które pomagają w rozwiązywaniu problemów. Błąd zawiera te informacje:

  • Przyczyna
  • Atrybuty niestandardowe zdefiniowane przez użytkownika