Obsługa awarii

Wyświetlasz dokumentację Apigee Edge.
Otwórz dokumentację Apigee X.
info

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

Gdy po wywołaniu przez aplikację klienta 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ć niestandardową obsługę błędów w Edge.

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 implementowanie 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 niestandardowych błędów za pomocą zasady RaiseFault Podczas działania interfejsu API zgłaszaj niestandardowe błędy za pomocą zasady RaiseFault.
Określanie 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.
Kolejność wykonywania reguł błędów Poznaj kolejność wykonywania reguł błędów w proxy interfejsu API i docelowych punktach końcowych.
Zdefiniuj domyślną regułę błędu Zdefiniuj domyślną regułę błędu, aby obsługiwać ogólne błędy w interfejsie API.

Jak występują błędy

Najpierw omówimy jak powstają błędy. Wiedza o tym, jak występują błędy, pomaga planować różne sytuacje, w których chcesz wdrożyć niestandardową obsługę błędów.

Błędy automatyczne

W tych sytuacjach serwer proxy interfejsu API automatycznie zgłasza błąd:

  • 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. (Rodzaje 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.

Niestandardowe komunikaty o błędach

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 serwera proxy interfejsu API.

Zasady RaiseFault możesz dodać do przepływu proxy interfejsu API w taki sam sposób jak inne zasady. W przykładzie konfiguracji serwera proxy poniżej 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>

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

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

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

Gdy serwer proxy zgłosi błąd:

Zamykanie potoku serwera proxy

Gdy w proxy interfejsu API wystąpi błąd, niezależnie od jego przyczyny, proxy opuszcza normalny potok przepływu, przechodzi w stan błędu i zwraca do aplikacji klienckiej komunikat o błędzie. Gdy proxy interfejsu API przejdzie w stan błędu, nie może już przywrócić przetwarzania do normalnego potoku przepływu.

Załóżmy na przykład, że serwer proxy interfejsu API ma zasady w tej kolejności w żądaniu ProxyEndpoint:

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

Jeśli podczas weryfikacji klucza interfejsu API wystąpi błąd, serwer proxy interfejsu API przechodzi w stan błędu. Zasady dotyczące limitu i konwersji 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 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 przez Ciebie warunków.
  2. Sekcja <DefaultFaultRule>, która w tych sytuacjach wywołuje domyślny komunikat o błędzie:
    • Nie zdefiniowano żadnych <FaultRules>.
    • Nie zostanie wykonane żadne istniejące <FaultRules>.
    • 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 one istnieją, ale nie wywołały niestandardowego błędu, serwer proxy wyśle własny domyślny komunikat wygenerowany przez Edge.

Prosty przykład 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 będą go otrzymywać, np. deweloperów aplikacji na iOS lub wewnętrznej grupy testowej, która ma własne wymagania dotyczące formatu komunikatów o błędach.

Oto podstawowy przykład tworzenia niestandardowego komunikatu o błędzie, który pozwoli Ci poradzić sobie z tym problemem. Wymaga to 1) zasady, która definiuje niestandardowy komunikat, oraz 2) reguły FaultRule, która wykonuje zasadę, gdy serwer proxy przechodzi w stan błędu.

1. Utwórz zasadę, która określa 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 zasady 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 zasad dotyczących wiadomości z kluczem interfejsu API na poprzednim rysunku.

Oto przykład zasad AssignMessage, które:

  • Zwraca wiadomość w formacie 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ę przyczyny HTTP (zastępuje domyślną frazę „Nieautoryzowano” w przypadku tego błędu braku klucza interfejsu API). Wyjaśnienie 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ź do 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."}

Tak, to trochę głupie, ale pokazuje, co jest możliwe. Dzięki temu deweloper otrzymujący komunikat wie, że zapomniał uwzględnić klucz interfejsu API jako parametr zapytania.

Jak ta zasada jest egzekwowana? W następnej sekcji dowiesz się, jak to zrobić.

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, gdy nie zostanie wykonana żadna z reguł FaultRule, wyświetlić 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 FaultRule w punkcie końcowym proxy i punkcie końcowym docelowym znajdziesz w dalszej części tego artykułu.
  • <Name> – nazwa zasady do wykonania. Nazwa pochodzi z atrybutu name elementu nadrzędnego zasady, jak pokazano w przykładzie zasady powyżej.
  • <Condition> – Edge ocenia 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 elementów TargetEndpoint i ProxyEndpoint, co opisano w sekcji Wiele reguł FaultRule i logika wykonywania). Jeśli nie podasz warunku, reguła FaultRule będzie automatycznie spełniona. Nie jest to jednak najlepsze rozwiązanie. Każda reguła FaultRule powinna mieć własny warunek.

  • <DefaultFaultRule> – jeśli nie zostanie wykonana żadna 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. W przeciwieństwie do niestandardowego <FaultRule> element <DefaultFaultRule> nie ocenia elementu <Condition> na poziomie reguły zewnętrznej. Aby warunkowo wykonać zasadę w ramach elementu <DefaultFaultRule>, dodaj wewnętrzny element <Condition> do elementu <Step> w elemencie <DefaultFaultRule>.

    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ź służy dwóm celom: dostarcza informacji przydatnych dla deweloperów, a jednocześnie zaciemnia 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> i <TargetEndpoint>. Ostatecznie jednak, gdy serwer proxy interfejsu API przechodzi w stan błędu, wykonywana jest tylko jedna reguła FaultRule.

W tej sekcji opisujemy 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 reguła FaultRule. W tej sekcji znajdziesz też wskazówki dotyczące tego, kiedy należy definiować FaultRules w <ProxyEndpoint>, a kiedy w <TargetEndpoint>. Opisujemy też relację między FaultRules a zasadą RaiseFault.

Wykonanie FaultRules

Oto logika, której Edge używa, gdy proxy interfejsu API przechodzi w stan błędu. Pamiętaj, że istnieje niewielka różnica między oceną FaultRules w ProxyEndpoint a TargetEndpoint.

  1. Edge ocenia reguły FaultRules w elementach ProxyEndpoint lub TargetEndpoint w zależności od tego, gdzie wystąpił błąd:
    • ProxyEndpoint – Edge zaczyna od dolnej <FaultRule> w konfiguracji XML i przechodzi w górę, oceniając <Condition> każdego <FaultRule> (warunek „zewnętrzny”, a nie „wewnętrzne” warunki <Step>).
    • TargetEndpoint – Edge zaczyna od góry <FaultRule> w konfiguracji 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 reguła FaultRule nie ma warunku, domyślnie przyjmuje wartość „prawda”.
    • Gdy wykonywana jest reguła FaultRule, wszystkie kroki w niej zawarte są oceniane po kolei, 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 przyjmuje wartość „prawda”, są wykonywane (warunki, które przyjmują 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. Element <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 usłudze ProxyEndpoint odbywa się od dołu do góry, więc zacznij od ostatniej reguły FaultRule w poniższym przykładzie i przejdź do góry. 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ł FaultRules 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ł dotyczących błędów

Jak widać w poprzednim przykładzie, kolejność umieszczania reguł FaultRules 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 ocena jest przeprowadzana od dołu do góry, więc 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 odbywa się 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

W ramach elementu FaultRule możesz wykonywać dowolne zasady, umieszczając je w elementach Steps. Możesz na przykład wykonać zasadę AssignMessage, aby sformatować odpowiedź dla aplikacji klienta, a następnie zarejestrować wiadomość za pomocą zasady 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 niepowodującym przejścia w stan błędu: atrybut continueOnError w zasadach.

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

Oto jednak przykład błędu, który nie powoduje przejścia serwera proxy 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" (na przykład 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 w przypadku 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 klienta 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 <TargetEndpoint> odpowiedzi, a normalny przepływ serwera proxy interfejsu API nie będzie kontynuowany do <ProxyEndpoint>. Jeśli masz zdefiniowane FaultRules tylko w <ProxyEndpoint>, nie będą one obsługiwać tego błędu.

Oto kolejny przykład. Jeśli zasada RaiseFault w <ProxyEndpoint>odpowiedzi 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ż ze sobą współpracują. W tej sekcji wyjaśniamy, jaki jest związek między tymi dwoma pojęciami. Zrozumienie tej zależności powinno pomóc Ci w projektowaniu obsługi błędów, zwłaszcza jeśli chcesz korzystać z 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>

    Zasady RaiseFault wysyłają 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 i potencjalnie uruchomi zasadę FaultRule? W tym miejscu sytuacja może się nieco skomplikować. Jeśli zasada RaiseFault zwraca komunikat o błędzie i zostanie wywołana zasada FaultRule, która również zwróci komunikat o błędzie, co zostanie zwrócone do aplikacji klienckiej?

  • Ponieważ zasada FaultRule lub DefaultFaultRule jest wykonywana po zasadzie RaiseFault, dane odpowiedzi zasady FaultRule mają wyższy priorytet.
  • Dane odpowiedzi zasady RaiseFault (kod stanu, fraza przyczyny lub ładunek wiadomości) są używane, jeśli nie zostały ustawione przez zasady FaultRule lub DefaultFaultRule.
  • Jeśli zasady RaiseFault 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 zasadę FaultRule oraz co jest zwracane do aplikacji klienckiej. Przykłady są krótkie, a nie zgodne ze sprawdzonymi metodami.

Aplikacja kliencka otrzymuje:

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

<- Zestawy zasad dotyczących reguł błędów ustawiają tę wartość:

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

<- RaiseFault policy sets this:

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 dotyczące błędów związanych z zasadami

Zmienne fault.name i {policy_namespace}.{policy_name}.failed są dostępne, gdy zasada zgłasza 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 zapoznaj się ze zmiennymi przepływu w każdym temacie dokumentacji zasad.

Inne dostępne zmienne

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

  • Zmienne zasady, które nie zostały spełnione.
  • Zmienne wiadomości HTTP, które istnieją 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 do śledzenia i temató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 proxy interfejsu API. Ważne jest, aby 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 mechanizmów obsługi błędów:

  • Dla 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 typowe jest używanie wielu 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 zasad, 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 wprowadzać zmiany iteracyjnie, ale wymaga to ponownego wdrożenia serwera proxy). Takie podejście pozwala wykrywać 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ętrznych kroku. Jeśli na przykład w przepływie żądania 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 w obu przypadkach limit zostanie przekroczony). 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 jednej reguły błędu, która jest wykonywana, gdy ta zasada zawiedzie. Uwzględnij w niej kilka 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 na każdy typ 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 reguły FaultRules w miejscach, w których wystąpią błędy (po stronie klienta <ProxyEndpoint> lub po stronie docelowej <TargetEndpoint>). Uwzględnij reguły 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ć wiadomość do aplikacji klienta. Idealna do tego jest zasada AssignMessage. Jeśli chcesz śledzić błędy, możesz też zarejestrować wiadomość 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 zasada RaiseFault resetuje kod stanu HTTP, nie używaj zasady FaultRule do resetowania kodu stanu. Najgorsze, co może się zdarzyć, to zwrócenie do aplikacji klienta domyślnego kodu stanu.
  • <DefaultFaultRule> execution:
    • Reguła <DefaultFaultRule> jest wykonywana automatycznie, gdy nie jest wykonywana żadna inna reguła FaultRule. Nie umieszczaj elementu podrzędnego <Condition> na poziomie reguły w elemencie <DefaultFaultRule>. Aby warunkowo wykonać zasadę w <DefaultFaultRule>, umieść element <Condition> w jego elemencie podrzędnym <Step>.
    • 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>.

Wzorzec scentralizowanej obsługi błędów wielokrotnego użytku

W tym poście na forum 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ć regułę FaultRule, musisz edytować konfigurację XML elementu ProxyEndpoint lub TargetEndpoint. Aby wprowadzić tę zmianę, możesz użyć interfejsu Edge w panelu Kod widoku Programowanie w przypadku serwera proxy interfejsu API lub edytować plik XML, który definiuje ProxyEndpoint lub TargetEndpoint.

Jeśli tworzysz reguły FaultRule 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 jeszcze nieutworzonych zasad, 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, aby wygenerować niestandardowy komunikat z odpowiedzią na warunek błędu. Zasada AssignMessage umożliwia skonfigurowanie odpowiedzi HTTP z elementami ładunku, kodu stanu HTTP, nagłówków i frazy przyczyny.

Poniższy przykład pokazuje typową konfigurację 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 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 sprawdzoną metodą należy zdefiniować jasne odpowiedzi o błędach z interfejsów API. Dzięki temu możesz przekazywać klientom spójne i przydatne informacje.

Poniższy przykład zasad AssignMessage używa tagów <Payload>, <StatusCode> i <ReasonPhase> do zdefiniowania niestandardowej odpowiedzi o błędzie, która jest odsyłana 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>

Ta odpowiedź zawiera:

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

Tworzenie elementu DefaultFaultRule

Reguła DefaultFaultRule działa jako moduł 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ślne obsługiwanie 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>

Element DefaultFaultRule jest zwykle używany 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 proxy interfejsu API zwraca błąd, którego nie możesz określić. Użyj elementu DefaultFaultRule, aby wywołać te zasady 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 funkcji PostClientFlow

PostClientFlow to jedyny przepływ, który jest wykonywany po przejściu 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 do tego przepływu zasady MessageLogging nie jest technicznie obsługą błędów, możesz używać tej zasady do rejestrowania informacji w przypadku wystąpienia błędu. Jest on wykonywany niezależnie od tego, czy proxy działa prawidłowo, czy nie. Dlatego w ramach PostClientFlow możesz umieścić zasady rejestrowania wiadomości i mieć pewność, że zawsze zostaną one 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żywana jest reguła FaultRule w elementach ProxyEndpoint lub TargetEndpoint. Dzieje się tak, ponieważ wartość domyślna elementu continueOnError w zasadach to false, co oznacza, że gdy w zasadach wystąpi błąd, sterowanie jest przekierowywane 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 w jakiejś formie.

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 zasadzie VerifAPIKey wystąpił błąd, wykonywana jest zasada o nazwie FaultInFlow. W przeciwnym razie zasada FaultInFlow zostanie pominięta. 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 PreFlow <Step>, 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 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 jednak 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 „niepowodzenie”. 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 w przypadku 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 powodzenie, wraz z domyślnymi kodami HTTP. Traktując te kody jako sukces, TargetEndpoint przejmuje przetwarzanie komunikatu 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ć w 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 punkt końcowy TargetEndpoint korzysta z 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 błędów

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 związanych z zasadami)
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 i 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ń na poziomie sieci lub 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 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 celu, przekroczenia limitu czasu, błędy TLS/SSL i błędy związane z przesyłaniem danych w blokach
System Niezdefiniowane błędy w czasie działania
Pamięć OutOfMemory, GCOverLimit Błędy związane z pamięcią
Wątek RogueTaskTerminated Błędy, takie jak zakończenie niekontrolowanych zadań
Zasady Błędy dotyczące każdego typu zasad są zdefiniowane w dokumentacji zasad.

Błąd zawsze zawiera opis tekstowy 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