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 żą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 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. |
| 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 serwerze proxy interfejsu API i docelowych punktach końcowych. |
| Określanie domyślnej reguły błędu | Zdefiniuj domyślną regułę błędu, aby obsługiwać ogólne błędy w interfejsie API. |
Jak występują błędy
Najpierw wyjaśnimy, 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
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.
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 serwera proxy interfejsu API.
Zasadę RaiseFault możesz dodać do przepływu serwera proxy interfejsu API w taki sam sposób jak każdą inną zasadę. 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 forach społeczności Apigee:
Działanie serwerów proxy interfejsu API w przypadku wystąpienia błędów
Co się dzieje, gdy serwer proxy zgłosi błąd.
Wyjście z 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 komunikat o błędzie do aplikacji klienckiej. Gdy 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 interfejsu API zasady są ułożone w tej kolejności:
- Weryfikowanie klucza interfejsu API
- Limit
- 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 serwery proxy interfejsu API sprawdzają też (w kolejności) obecność tych elementów w konfiguracji serwera proxy interfejsu API, zanim zwrócą do aplikacji klienckiej domyślny komunikat o błędzie:
- 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. - Sekcja
<DefaultFaultRule>, która w tych sytuacjach wywołuje domyślny komunikat o błędzie:- Nie zdefiniowano żadnych
<FaultRules>. - Nie wykonuje się żadnych istniejących
<FaultRules>. - Element
<AlwaysEnforce>ma wartość „true”.
- Nie zdefiniowano żadnych
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 został wywołany żaden niestandardowy błąd, 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 osoby, która ostatecznie go otrzyma, 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 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).

Dzięki temu możesz utworzyć zasadę 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.
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ępując domyślną frazę „Unauthorized” w przypadku tego błędu braku klucza API). Wyjaśnienie przyczyny 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 wiadomość wie, że zapomniał dołączyć 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 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 reguł FaultRules 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 atrybutunameelementu nadrzędnego zasady, jak pokazano we wcześniejszym przykładzie zasady.-
<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 spełniona. 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 opcja.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 zarówno w <ProxyEndpoint>, jak i w <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>, oraz opis relacji 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 ocena FaultRules w ProxyEndpoint nieco różni się od oceny w TargetEndpoint.
- 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 elementu
<FaultRule>w konfiguracji XML i przechodzi w górę, oceniając<Condition>każdego elementu<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>).
- ProxyEndpoint – Edge zaczyna od najniższego elementu
- Wykonuje pierwszą regułę FaultRule, której warunek jest prawdziwy. Jeśli FaultRule nie ma warunku, domyślnie ma 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, które mają warunek
<Condition>o wartości „true”, są wykonywane (warunki o wartości „false” 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.
- 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, które mają warunek
- 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.
Wykonanie 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 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ł 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ł błędów
Jak widać w poprzednim przykładzie, kolejność umieszczania elementów 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 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 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
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 nieprzejście 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ść true, nie zostanie 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 w przypadku continueOnError="true" znajdziesz w artykule Obsługa błędów zasad w bieżącym przepływie.
Gdzie zdefiniować FaultRules: ProxyEndpoint lub TargetEndpoint
Gdy w proxy interfejsu API wystąpi błąd, pojawia się on w <ProxyEndpoint> (żądanie z aplikacji klienta lub odpowiedź do niej) lub w <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 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ż ze sobą 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 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>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 i potencjalnie uruchomi zasadę FaultRule? W tym miejscu sytuacja może się nieco skomplikować. Jeśli zasada RaiseFault zwróci 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ż 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 zostały ustawione przez FaultRule lub DefaultFaultRule.
- Jeśli zasada 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 FaultRule oraz co jest zwracane do aplikacji klienta. 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 |
<- Fault rules policy sets this: Status Code: [none] Reason Phrase: Something happened Payload: {"Whoa":"Sorry."} Header: errorNote: gremlins |
Ta zasada RaiseFault ustawia:
Status Code: 468
Reason Phrase: Can't do that
Payload: {"DOH!":"Try again."}
Header:
errorNote: woops
|
Warunki dotyczące budynku
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 przedstawić 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 dotyczącymi zasad
Zmienne fault.name i {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 przyjmuje 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.
- Zasada RaiseFault:
raisefault.failed(taka sama w przypadku wszystkich zasad RaiseFault) - VerifyAPIKey policy:
oauthV2.{policy_name}.failed, na przykładoauthV2.Verify-API-Key-1.failed - Zasady dotyczące limitów i zasady SpikeArrest:
ratelimit.{policy_name}.failednp.ratelimit.Quota-1.failed
Inne dostępne zmienne
Gdy proxy interfejsu API przejdzie 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 HTTPresponse.status.code,message.content,error.contentitd. Jeśli zasada dotycząca limitu nie została spełniona, możesz użyć zmiennejratelimit.{quota_policy_name}.exceed.count. Skorzystaj z narzędzia śledzenia i tematów referencyjnych dotyczących zasad, aby dowiedzieć się, które zmienne i dane HTTP są dostępne.
Więcej informacji
-
Warunki: Odwołanie do warunków i Zmienne przepływu i warunki
- Błędy: Odwołanie do błędu związanego z zasadami
- Zmienne: odwołanie do zmiennych. Zmienne dostępne w przypadku poszczególnych zasad znajdziesz na stronach odwołań do zasad.
Sprawdzone metody obsługi błędów
Obsługa błędów jest ważnym zadaniem projektowym w architekturze podczas tworzenia 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 mechanizmów 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 jest prawdziwa czy fałszywa. 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 1 regułę 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 żą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ć zmienneexceed.countw 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 nie działa, i uwzględnij w niej wiele kroków odpowiadających 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>). Uwzględnij 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 klienckiej. 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 FaultRule, 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 klienckiej domyślnego kodu stanu.
-
<DefaultFaultRule>wykonanie:- Jeśli chcesz, aby element
<DefaultFaultRule>był zawsze wykonywany, gdy nie jest wykonywana żadna inna reguła FaultRule, nie umieszczaj w nim 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>.
- Jeśli chcesz, aby element
Wzór scentralizowanej, wielokrotnego użytku obsługi błędów
W tym poście na forum społeczności Apigee opisano wzorzec centralnego obsługiwania 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 serwera proxy interfejsu API lub edytując 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 elemencie FaultRule możesz umieścić dowolne zasady, ale najczęściej używasz zasad AssignMessage, aby wygenerować 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ż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 odwołujesz się do zasady AssignMessage według nazwy w zasadzie FaultRule:
<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 elemencie FaultRule powoduje błąd.
- Każda zasada w elemencie FaultRule jest typu RaiseFault.
Określanie 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> 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óry można się kontaktować 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 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ś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>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>Reguła DefaultFaultRule służy m.in. do określania typu błędu, który występuje, gdy nie można go inaczej ustalić. Na przykład serwer proxy interfejsu API nie działa z powodu błędu, którego nie możesz określić. Użyj elementu 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 do tego przepływu zasady MessageLogging nie jest technicznie obsługą błędów, możesz jej używać do rejestrowania informacji w przypadku wystąpienia błędu. Jest ona wykonywana niezależnie od tego, czy proxy działa prawidłowo, czy nie. Dlatego możesz umieścić zasady rejestrowania wiadomości w PostClientFlow i mieć pewność, że zawsze będą wykonywane.
Obsługa błędów zasad w bieżącym przepływie
W pokazanych do tej pory przykładach użyto elementu FaultRule w elementach ProxyEndpoint lub TargetEndpoint do obsługi błędów zasad w ramach stanu błędu. 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 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 wykonana zostanie zasada RaiseFault, bieżący przepływ zostanie zakończony, a sterowanie zostanie przekazane do stanu błędu.
Jednym z zastosowań zasady RaiseFault jest testowanie określonego warunku, którego inna zasada może nie wykryć. W powyższym przykładzie 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 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 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 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 jedynie 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 powodzenie, a także domyślne kody HTTP. Traktując te kody jako powodzenie, 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ć 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, która wysłała żą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 i 4xx | |
| Błędy wyznaczania trasy | 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 żadnej konfiguracji BasePath w przypadku żadnego 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 podczas 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 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
