אתם צופים במסמכי התיעוד של Apigee Edge.
כדאי לעיין במסמכי התיעוד של Apigee X. מידע
יכולות להיות הרבה שגיאות כשפרוקסי של API מטפל בבקשות מאפליקציות. לדוגמה, יכול להיות שיהיו בעיות ברשת כשפרוקסי של API מתקשר עם שירותי קצה עורפי, או שאפליקציות יציגו פרטי כניסה שתוקפם פג, או שפורמט של הודעות בקשה יהיה שגוי, וכן הלאה.
כשמתרחשת שגיאה אחרי שאפליקציית לקוח קוראת ל-proxy ל-API, הודעת שגיאה מוחזרת ללקוח. כברירת מחדל, הלקוח מקבל הודעת שגיאה, שלרוב היא לא ברורה, ללא פרטים או הנחיות. אבל אם רוצים להחליף את הודעות השגיאה שמוגדרות כברירת מחדל בהודעות מותאמות אישית שימושיות יותר, ואפילו להוסיף להן דברים כמו כותרות HTTP נוספות, צריך להגדיר טיפול מותאם אישית בשגיאות ב-Edge.
טיפול בשגיאות בהתאמה אישית מאפשר לכם גם להוסיף פונקציונליות כמו רישום הודעות ביומן בכל פעם שמתרחשת שגיאה.
לפני שנדון בהטמעה של טיפול מותאם אישית בשגיאות בשרתי proxy של API, כדאי להבין איך שגיאות מתרחשות ואיך שרתי proxy של API מגיבים להן.
סרטונים
כדי לקבל מידע נוסף על טיפול בשגיאות, כדאי לצפות בסרטונים הבאים.
| וידאו | תיאור |
|---|---|
| מבוא לטיפול בשגיאות ולזרימות שגיאות | מידע על טיפול בשגיאות ומה קורה כשמתרחשת שגיאה ב-proxy ל-API. |
| טיפול בשגיאות באמצעות כללי שגיאות | איך מטפלים בשגיאות באמצעות כללי שגיאות |
| העלאת תקלות מותאמות אישית באמצעות מדיניות RaiseFault | אפשר להעלות תקלות מותאמות אישית במהלך זמן הריצה של ה-API באמצעות מדיניות RaiseFault. |
| הגדרת כללי תקלות בשרת proxy ל-API ובנקודות קצה של יעד | להגדיר כללי תקלות בשרת ה-proxy ל-API ובנקודות הקצה של היעד, ולהבין את ההבדלים. |
| הסבר על סדר הביצוע של כללי תקלות | הסבר על סדר הביצוע של כללי תקלות ב-API Proxy ובנקודות הקצה של היעד. |
| הגדרת כלל ברירת מחדל | מגדירים כלל ברירת מחדל לטיפול בשגיאות כלליות ב-API. |
איך מתרחשות שגיאות
קודם נסביר איך מתרחשות שגיאות. הבנה של אופן התרחשות השגיאות עוזרת לתכנן את המצבים השונים שבהם רוצים להטמיע טיפול בשגיאות מותאם אישית.
שגיאות אוטומטיות
פרוקסי של API מחזיר שגיאה באופן אוטומטי במצבים הבאים:
- מדיניות מחזירה שגיאה. לדוגמה, אם קריאה ל-API שולחת מפתח שפג תוקפו, מדיניות VerifyAPIKey זורקת שגיאה באופן אוטומטי. או אם מספר הקריאות ל-API חורג ממגבלה מסוימת, מדיניות Quota או מדיניות SpikeArrest זורקת שגיאה. (בהפניה לשגיאות במדיניות מפורטים סוגי השגיאות שמדיניות יכולה להחזיר).
- יש בעיה בזרימת ההודעות של ה-proxy ל-API, כמו שגיאת ניתוב.
- יש כשל בקצה העורפי, כמו שגיאת HTTP בגלל כשלים ברמת הפרוטוקול, שגיאות TLS/SSL או שירות יעד לא זמין.
- יש כשל ברמת המערכת, כמו חריגה של חוסר זיכרון.
מידע נוסף על השגיאות האלה זמין בקטע טקסונומיה של תקלות במאמר הזה.
שגיאות בהתאמה אישית
במקרים שבהם לא מתרחשת שגיאה אוטומטית, יכול להיות שתרצו להגדיר שגיאה מותאמת אישית. לדוגמה, אם התשובה מכילה את המילה unavailable (לא זמין), או אם קוד הסטטוס של HTTP גדול מ-201. כדי לעשות את זה, מוסיפים מדיניות RaiseFault למקום המתאים בתהליך של שרת proxy ל-API.
אפשר להוסיף מדיניות RaiseFault לזרימת proxy ל-API בדיוק כמו שמוסיפים כל מדיניות אחרת. בדוגמה הבאה להגדרת שרת proxy, המדיניות Raise-Fault-1 מצורפת לתגובה של TargetEndpoint. אם המילה unavailable (לא זמין) מופיעה בתשובה משירות היעד, מדיניות RaiseFault מופעלת ומוצגת שגיאה.
<TargetEndpoint name="default">
...
<Response>
<Step>
<Name>Raise-Fault-1</Name>
<Condition>(message.content Like "*unavailable*")</Condition>
</Step>
</Response>הדוגמה הזו נועדה רק להראות שאפשר להציג שגיאות בהתאמה אישית. בקטע FaultRules לעומת המדיניות RaiseFault יש פרטים נוספים על המדיניות RaiseFault.
דוגמאות נוספות זמינות בפוסטים האלה בפורומים של קהילת Apigee:
מה קורה כשמתרחשות שגיאות בשרתי proxy של API
מה קורה כשמתרחשת שגיאה בשרת proxy.
יציאה מצינור עיבוד הנתונים של שרת ה-proxy
כשמתרחשת שגיאה ב-proxy ל-API, לא משנה איך היא מתרחשת, הוא יוצא מצינור התהליך הרגיל, עובר למצב שגיאה ומחזיר הודעת שגיאה לאפליקציית הלקוח. אחרי ש-proxy ל-API עובר למצב שגיאה, הוא לא יכול להחזיר את העיבוד לצינור התהליך הרגיל.
לדוגמה, נניח של-proxy ל-API יש מדיניות בסדר הבא בבקשה של ProxyEndpoint:
- אימות מפתח API
- מכסה
- JSON ל-XML
אם מתרחשת שגיאה במהלך אימות מפתח ה-API, proxy ל-API עובר למצב שגיאה. הכללים Quota ו-JSON to XML לא מופעלים, ה-proxy לא ממשיך אל TargetEndpoint, ומוחזרת הודעת שגיאה לאפליקציית הלקוח.
בדיקה של FaultRules
במצב שגיאה, proxy ל-API בודקים גם את הנוכחות של הרכיבים הבאים (לפי הסדר) בהגדרת proxy ל-API לפני שהם מחזירים הודעת שגיאה שמוגדרת כברירת מחדל לאפליקציית הלקוח:
- קטע
<FaultRules>, שמכיל את הלוגיקה להפעלת הודעות שגיאה מותאמות אישית (ומדיניות אחרת) על סמך תנאים ספציפיים שאתם מגדירים. - קטע
<DefaultFaultRule>, שמפעיל הודעת שגיאה שמוגדרת כברירת מחדל במצבים הבאים:- לא הוגדרו
<FaultRules>. - לא מופעלות
<FaultRules>קיימות. - הרכיב
<AlwaysEnforce>מוגדר כ-true.
- לא הוגדרו
בעצם, פרוקסי ה-API מאפשר לכם להחזיר הודעת שגיאה מותאמת אישית ולהפעיל לוגיקה אחרת. אם שרת ה-proxy לא מוצא את שני החלקים האלה, או שהם קיימים אבל לא הופעלה שגיאה מותאמת אישית, שרת ה-proxy שולח הודעת ברירת מחדל משלו שנוצרה על ידי Edge.
דוגמה פשוטה לטיפול בשגיאות
נתחיל עם דוגמה פשוטה, שבה קריאה ל-proxy ל-API לא מכילה מפתח API נדרש. כברירת מחדל, התגובה שמוחזרת לאפליקציית הלקוח היא:
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"}}}
יכול להיות שהמשתמשים ב-API יוכלו להבין את הודעת השגיאה, אבל יכול להיות שלא. הרבה שגיאות שמופיעות כברירת מחדל הן יותר מורכבות וקשה יותר לפענח אותן.
מפתחי API צריכים לשנות את ההודעה הזו כך שתתאים לצרכים של מי שיקבלו את הודעת השגיאה, בין אם מדובר במפתחי אפליקציות ל-iOS או בקבוצת בדיקות פנימית שיש לה דרישות משלה לגבי פורמט הודעת השגיאה.
הנה דוגמה בסיסית לאופן שבו יוצרים הודעת שגיאה בהתאמה אישית כדי לטפל בשגיאה הזו. כדי לעשות את זה, צריך 1) מדיניות שמגדירה את ההודעה המותאמת אישית, ו-2) FaultRule שמפעיל את המדיניות כשה-proxy עובר למצב שגיאה.
1. יצירת מדיניות שמגדירה את ההודעה המותאמת אישית
קודם כול, יוצרים מדיניות שמגדירה את הודעת השגיאה המותאמת אישית. אפשר להשתמש בכל סוג של מדיניות, כמו מדיניות AssignMessage, שיכולה להגדיר מטען ייעודי וכותרות HTTP אופציונליות כמו קוד סטטוס ומשפט סיבה. האפשרות 'הקצאת הודעה' מתאימה במיוחד למצבים כאלה. היא מאפשרת לכם לשלוט במטען הייעודי (payload) של ההודעה, להגדיר קוד סטטוס של HTTP שונה, להגדיר משפט סיבה שונה של HTTP ולהוסיף כותרות HTTP.
אל תצרפו את המדיניות לזרימה כלשהי ב-proxy ל-API. מספיק שהוא פשוט קיים בחבילת ה-proxy. כדי לעשות זאת בכלי לעריכת שרת proxy בממשק הניהול, עוברים לכרטיסייה Develop (פיתוח), ובחלונית הניווט לוחצים על סמל הפלוס בסרגל Policies (מדיניות).

כך תוכלו ליצור מדיניות בלי לצרף אותה לזרימה ב-proxy ל-API. מדיניות שלא מצורפת לאף תהליך מסומנת בסמל 'מנותק' ברשימת המדיניות, כמו שמוצג ליד מדיניות ההודעות של מפתח ה-API באיור הקודם.
הדוגמה הבאה היא של מדיניות AssignMessage ש:
- הפונקציה מחזירה הודעת JSON.
- הגדרת קוד סטטוס של HTTP (911, שהוא קוד סטטוס ברור שלא קיים, רק כדי להמחיש את הגמישות שיש לכם). קוד הסטטוס מופיע בכותרת ה-HTTP.
- מגדיר משפט סיבה של HTTP (כדי להחליף את משפט הסיבה 'לא מורשה' שמוגדר כברירת מחדל לשגיאה הזו של מפתח API חסר). המשפט שמסביר את הסיבה מופיע לצד קוד הסטטוס בכותרת של HTTP.
- יוצרת כותרת HTTP חדשה בשם
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>
כשהמדיניות הזו מופעלת, התגובה לאפליקציית הלקוח תיראה כך. משווים אותה לתשובה שמופיעה כברירת מחדל, שמוצגת קודם.
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."}
כן, זה קצת טיפשי, אבל זה מראה לכם מה אפשר לעשות. לפחות עכשיו המפתח שמקבל את ההודעה יודע שהוא שכח לכלול מפתח API כפרמטר של שאילתה.
אבל איך המדיניות הזו מיושמת? בקטע הבא נסביר איך עושים את זה.
2. יוצרים את הרכיב <FaultRule> שיפעיל את המדיניות
בקטעים <ProxyEndpoint> או <TargetEndpoint> של הגדרת ה-proxy, מוסיפים בלוק XML <FaultRules> שמכיל קטע <FaultRule> אחד או יותר. כל רכיב FaultRule מייצג שגיאה שונה שרוצים לטפל בה. בדוגמה הפשוטה הזו נשתמש רק ב-FaultRule אחד כדי להראות לכם ממה הוא מורכב.
כדאי גם להוסיף <DefaultFaultRule> כדי לספק הודעת שגיאה כללית מותאמת אישית אם אף אחד מהכללים של FaultRule לא מופעל.
דוגמה
<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>נקודות עיקריות:
- הכללים FaultRules מוגדרים ב-ProxyEndpoint. זה חשוב. בהמשך נסביר יותר על מיקום של FaultRules ב-ProxyEndpoint לעומת TargetEndpoint.
-
<Name>– שם המדיניות להפעלה. השם מגיע מהמאפייןnameשל המדיניות ברכיב ההורה, כפי שמוצג בדוגמה למדיניות שמופיעה למעלה. -
<Condition>– Edge מעריך את התנאי ומבצע את המדיניות רק אם התנאי מתקיים. אם יש כמה רכיבי FaultRule שהערך שלהם הוא true, Edge מפעיל את הראשון שהערך שלו הוא true. (חשוב: סדר ההערכה של FaultRule, מלמעלה למטה או מלמטה למעלה, שונה בין TargetEndpoint לבין ProxyEndpoint, כפי שמתואר בקטע Multiple FaultRules and execution logic). אם לא מציינים תנאי, הערך של FaultRule הוא true באופן אוטומטי. אבל זו לא שיטה מומלצת. לכל רכיב FaultRule צריך להיות תנאי משלו. -
<DefaultFaultRule>– אם לא מופעל FaultRule מותאם אישית, מופעל<DefaultFaultRule>ונשלחת הודעה מותאמת אישית כללית יותר במקום הודעת ברירת המחדל המסתורית שנוצרת על ידי Edge. A<DefaultFaultRule>יכול לכלול גם<Condition>, אבל ברוב המקרים לא תכללו אותו, כי אתם רוצים שהוא יפעל בכל מקרה כמוצא אחרון.בדרך כלל משתמשים ב-DefaultFaultRule כדי להחזיר הודעת שגיאה גנרית לכל שגיאה בלתי צפויה. לדוגמה, הודעה שמכילה פרטים ליצירת קשר עם תמיכה טכנית. תגובת ברירת המחדל הזו משרתת שתי מטרות: היא מספקת מידע ידידותי למפתחים, וגם מסתירה כתובות URL של קצה עורפי או מידע אחר שאפשר להשתמש בו כדי לפגוע במערכת.
כמה רכיבי FaultRule ולוגיקת ביצוע
בקטע דוגמה פשוטה לטיפול בשגיאות השתמשנו בדוגמה פשוטה של FaultRule ותנאי יחידים. בפרויקט API בעולם האמיתי, עם כל השגיאות האפשריות שיכולות להתרחש, סביר להניח שיהיו לכם כמה רכיבי FaultRule ורכיב DefaultFaultRule גם ב-<ProxyEndpoint> וגם ב-<TargetEndpoint>. בסופו של דבר, רק כלל FaultRule אחד מופעל כש-proxy ל-API נכנס למצב שגיאה.
בקטע הזה מתואר הלוגיקה שבה Edge משתמש בטיפול ב-FaultRule, החל מהאופן שבו הוא מגיע ל-FaultRule יחיד לביצוע ועד לאופן שבו מטופלים תנאי Step 'פנימיים' כשמופעל FaultRule שלהם. בקטע הזה יש גם הנחיות לגבי המקרים שבהם כדאי להגדיר FaultRules ב-<ProxyEndpoint> לעומת <TargetEndpoint>, ומוסבר הקשר בין FaultRules לבין המדיניות RaiseFault.
ביצוע של FaultRules
בקצרה, הנה הלוגיקה שבה Edge משתמש כש-proxy ל-API עובר למצב שגיאה. שימו לב שיש הבדל קל בין ההערכה של FaultRules ב-ProxyEndpoint לבין ההערכה ב-TargetEndpoint.
- Edge מעריך את ה-FaultRules ב-ProxyEndpoint או ב-TargetEndpoint, בהתאם למיקום שבו השגיאה התרחשה:
- ProxyEndpoint – Edge מתחיל עם התחתון
<FaultRule>ב-XML של ההגדרה, וממשיך כלפי מעלה, תוך הערכה של<Condition>של כל<FaultRule>(התנאי 'החיצוני', לא התנאים 'הפנימיים'<Step>). - TargetEndpoint – Edge מתחיל עם החלק העליון של
<FaultRule>ב-XML של ההגדרה, וממשיך למטה. הוא מעריך את<Condition>של כל<FaultRule>(התנאי "החיצוני", לא התנאים "הפנימיים" של<Step>).
- ProxyEndpoint – Edge מתחיל עם התחתון
- מפעיל את first FaultRule שהתנאי שלו הוא true. אם ל-FaultRule אין תנאי, ברירת המחדל היא true.
- כשמפעילים FaultRule, כל השלבים בתוך FaultRule מוערכים לפי הסדר, מלמעלה למטה בהגדרת ה-XML. שלבים ללא תנאים מבוצעים באופן אוטומטי (המדיניות מופעלת), ושלבים עם תנאי
<Condition>שמוערך כ-true מבוצעים (תנאים שמוערכים כ-false לא מבוצעים). -
אם מתבצעת הפעלה של FaultRule, אבל לא מתבצעת הפעלה של אף אחד מהשלבים ב-FaultRule (כי התנאים שלהם מוערכים כ-false), הודעת השגיאה שמוגדרת כברירת מחדל שנוצרת על ידי Edge מוחזרת לאפליקציית הלקוח. הפעולה
<DefaultFaultRule>לא מתבצעת, כי Edge כבר ביצע את הפעולה FaultRule.
- כשמפעילים FaultRule, כל השלבים בתוך FaultRule מוערכים לפי הסדר, מלמעלה למטה בהגדרת ה-XML. שלבים ללא תנאים מבוצעים באופן אוטומטי (המדיניות מופעלת), ושלבים עם תנאי
- אם לא מופעל FaultRule, Edge מפעיל את
<DefaultFaultRule>, אם הוא קיים.
בהמשך מופיעות דוגמאות עם הערות בתוך הטקסט.
ביצוע של ProxyEndpoint
ההערכה של ProxyEndpoint FaultRules מתבצעת מלמטה למעלה, לכן כדאי להתחיל לקרוא את ה-FaultRule האחרון בדוגמה הבאה ולעבור למעלה. צריך לבדוק את 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>הפעלה של TargetEndpoint
ההערכה של TargetEndpoint FaultRules מתבצעת מלמעלה למטה, לכן כדאי להתחיל לקרוא את ה-FaultRule הראשון בדוגמה הבאה ולעבור למטה. צריך לבדוק את 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>סדר כללי התקלה
כפי שאפשר לראות בדוגמה הקודמת, הסדר שבו מציבים את רכיבי FaultRule חשוב, בהתאם לשאלה אם השגיאה מתרחשת ב-ProxyEndpoint או ב-TargetEndpoint.
לדוגמה:
| סדר של ProxyEndpoint | סדר של TargetEndpoint |
|---|---|
|
בדוגמה הבאה, מכיוון שההערכה מתבצעת מלמטה למעלה, מופעלת FaultRule 3, מה שאומר שלא מתבצעת הערכה של FaultRule 2 ו-FaultRule 1. 5. FaultRule 1: FALSE 4. FaultRule 2: TRUE 3. FaultRule 3: TRUE 2. FaultRule 4: FALSE 1. FaultRule: 5 FALSE |
בדוגמה הבאה, מכיוון שההערכה מתבצעת מלמעלה למטה, מתבצעת הפעלה של FaultRule 2, מה שאומר שלא מתבצעת הערכה של FaultRule 3, 4 ו-5. 1. FaultRule 1: FALSE 2. FaultRule 2: TRUE 3. FaultRule 3: TRUE 4. FaultRule 4: FALSE 5. FaultRule: 5 FALSE |
כללי מדיניות שצריך לכלול
אפשר להריץ כל מדיניות מ-FaultRule על ידי הוספתה ל-Steps. לדוגמה, אפשר להפעיל מדיניות AssignMessage כדי לעצב תגובה לאפליקציית הלקוח, ואז לרשום הודעה ביומן באמצעות מדיניות MessageLogging. המדיניות מופעלת לפי הסדר שבו היא מופיעה (מלמעלה למטה ב-XML).
כללי תקלות מופעלים רק במצב שגיאה (מידע על continueOnError)
יכול להיות שהכותרת הזו נראית כמו חזרה על דברים שכבר נאמרו, אבל יש ניואנס ספציפי שחשוב להכיר לגבי שגיאת proxy שגורמת ל-API proxy להיכנס למצב שגיאה – או ליתר דיוק, לא להיכנס למצב שגיאה: המאפיין continueOnError במדיניות.
לסיכום: proxy ל-API בודק את <FaultRules> ואת
<DefaultFaultRule> רק אם ה-proxy נכנס למצב שגיאה. כלומר, גם אם תנאי של FaultRule מחזיר את הערך true, הוא לא יופעל אם ה-proxy לא נמצא במצב שגיאה.
עם זאת, הנה דוגמה לשגיאה שמתרחשת וה-proxy לא נכנס למצב שגיאה. בכל מדיניות אפשר להגדיר מאפיין ברכיב ההורה שנקרא continueOnError.
המאפיין הזה חשוב מאוד בכל הנוגע לטיפול בשגיאות, כי הוא קובע אם ה-proxy נכנס למצב שגיאה אם המדיניות נכשלת. ברוב המקרים, כדאי להשאיר את ברירת המחדל continueOnError="false", שגורמת לכך שה-proxy יעבור למצב שגיאה אם המדיניות נכשלת, והטיפול בשגיאות המותאם אישית יופעל. עם זאת, אם continueOnError="true" (לדוגמה, אם לא רוצים שהכשל של קריאה לשירות יגרום להפסקת הביצוע של ה-proxy), ה-proxy לא יעבור למצב שגיאה אם המדיניות הזו תיכשל, וה-proxy לא יבדוק את FaultRules.
מידע על רישום שגיאות ביומן כשמשתמשים ב-continueOnError="true" זמין במאמר טיפול בשגיאות מדיניות בתהליך הנוכחי.
איפה מגדירים את FaultRules: ProxyEndpoint או TargetEndpoint
כשמתרחשת שגיאה ב-API proxy, השגיאה מתרחשת ב-<ProxyEndpoint> (בקשה מאפליקציית לקוח או תגובה לאפליקציית לקוח) או ב-<TargetEndpoint> (בקשה משירות יעד או תגובה משירות יעד). בכל מקום שבו השגיאה הזו מתרחשת, Edge מחפש את FaultRules.
לדוגמה, אם שרת היעד לא זמין (קוד סטטוס HTTP 503), פרוקסי ה-API יעבור למצב שגיאה בתגובה <TargetEndpoint>, והזרימה הרגילה של פרוקסי ה-API לא תמשיך אל <ProxyEndpoint>. אם הגדרתם FaultRules רק ב-<ProxyEndpoint>, הן לא יטפלו בשגיאה הזו.
הנה דוגמה נוספת. אם מדיניות RaiseFault בתגובה <ProxyEndpoint> מפעילה שגיאה, לא תתבצע הפעלה של FaultRule ב-<TargetEndpoint>.
ההבדל בין FaultRules לבין המדיניות RaiseFault
יכול להיות שכללי התקלות ומדיניות RaiseFault נשמעים כמו דרכים חלופיות לטיפול בתקלות, ובמובנים מסוימים זה נכון. אבל הם גם פועלים יחד. בסעיף הזה מוסבר הקשר בין השניים. הבנת הקשר הזה תעזור לכם לתכנן את הטיפול בשגיאות, במיוחד אם אתם רוצים להשתמש בשניהם.
בקצרה:
- כללי תקלות נבדקים תמיד כש-proxy ל-API נכנס למצב שגיאה.
-
המדיניות RaiseFault מאפשרת להעביר proxy ל-API למצב שגיאה כששגיאה לא הייתה מתרחשת אחרת.
לדוגמה, אם רוצים להציג שגיאה אם קוד הסטטוס של HTTP בתגובה משירות היעד גדול מ-200, מוסיפים מדיניות RaiseFault לזרימת התגובה. כתוב האתר שלך תיראה כך:
<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>המדיניות RaiseFault שולחת גם הודעת שגיאה לאפליקציית הלקוח.
מה קורה כשמדיניות RaiseFault מפעילה שגיאה, שמעבירה את ה-proxy למצב שגיאה, שעלול להפעיל FaultRule? כאן הדברים יכולים להיות קצת מסובכים. אם מדיניות RaiseFault מחזירה הודעת שגיאה ומופעל FaultRule ומחזיר הודעת שגיאה, מה מוחזר לאפליקציית הלקוח?
- מכיוון שהכלל FaultRule או DefaultFaultRule מופעלים אחרי המדיניות RaiseFault, נתוני התגובה של FaultRule הם אלה שקובעים.
- הנתונים של התגובה של מדיניות RaiseFault (קוד סטטוס, צירוף מילים לתיאור הסיבה או מטען ייעודי של הודעה) משמשים אם הנתונים האלה לא מוגדרים על ידי FaultRule או DefaultFaultRule.
- אם גם מדיניות RaiseFault וגם FaultRule מוסיפות כותרות HTTP מותאמות אישית, שתיהן נכללות בתגובה. שמות כפולים של כותרות יוצרים כותרת עם כמה ערכים.
בדוגמה הבאה אפשר לראות מה מוגדר על ידי מדיניות RaiseFault ו-FaultRule, ומה מוחזר לאפליקציית הלקוח. הדוגמאות קצרות ולא מיועדות לשימוש כשיטות מומלצות.
|
|
||
|
אפליקציית הלקוח מקבלת: Status Code: 468 Reason Phrase: Something happened Payload: {"Whoa":"Sorry."} Header: errorNote: woops,gremlins |
<- מדיניות כללי התקלה מגדירה את הערך הזה: Status Code: [none] Reason Phrase: Something happened Payload: {"Whoa":"Sorry."} Header: errorNote: gremlins |
<- מדיניות RaiseFault מגדירה את הערך הזה:
Status Code: 468
Reason Phrase: Can't do that
Payload: {"DOH!":"Try again."}
Header:
errorNote: woops
|
יצירת תנאים
התנאים הם המפתח להפעלת FaultRule. יוצרים תנאים של FaultRule באותו אופן שבו יוצרים תנאים אחרים ב-Edge, למשל תנאים של זרימות מותנות או של RaiseFault.
כדי להבין את שאר החלק הזה, הנה דוגמה לכלל שגיאה עם תנאי FaultRule חיצוני ותנאי לביצוע השלב פנימי.
<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>משתנים ספציפיים לשגיאות שקשורות למדיניות
המשתנים fault.name ו-{policy_namespace}.{policy_name}.failed זמינים כשמדיניות מחזירה שגיאה.
fault.name
אם מדיניות נכשלת, צריך לזהות את השגיאה בתנאי באמצעות המשתנה fault.name. לדוגמה:
<Condition>(fault.name = "policy_error_name")</Condition>
שם השגיאה מופיע בהודעת השגיאה שמוגדרת כברירת מחדל. לדוגמה, בשגיאה הבאה, שם השגיאה הוא FailedToResolveAPIKey. במקרה הזה, משתנה של זרימת נתונים בשם fault.name מוגדר לערך FailedToResolveAPIKey.
{"fault":{"faultstring":"Failed to resolve API Key variable request.queryparam.apikey","detail":{"errorcode":"steps.oauth.v2.FailedToResolveAPIKey"}}}
לכן התנאי ייראה כך:
<Condition>(fault.name = "FailedToResolveAPIKey")</Condition>
רשימת שגיאות המדיניות מופיעה בהפניה לשגיאות מדיניות.
{policy_namespace}.{policy_name}.failed
המשתנה *.failed זמין כשהמדיניות נכשלת. בהמשך מופיעות דוגמאות למשתני *.failed עבור מדיניות שונה.
לגבי מרחבי שמות של מדיניות, אפשר לעיין במשתני הזרימה בכל נושא הפניה למדיניות.
- RaiseFault policy:
raisefault.failed(זהה לכל כללי RaiseFault) - מדיניות VerifyAPIKey:
oauthV2.{policy_name}.failed, לדוגמה,oauthV2.Verify-API-Key-1.failed - מדיניות בנושא מכסות ומדיניות בנושא מניעת עליות פתאומיות:
ratelimit.{policy_name}.failed, לדוגמה,ratelimit.Quota-1.failed
משתנים זמינים אחרים
כש-proxy ל-API עובר למצב שגיאה, המשתנים היחידים שזמינים לשימוש בתנאים הם:
- המשתנים של המדיניות שנכשלה.
- משתני הודעת ה-HTTP שקיימים בנקודת הכשל. לדוגמה, אם מוצגת שגיאה בתגובה, רכיב FaultRule ב-
<TargetEndpoint>יכול להשתמש בנתוני HTTPresponse.status.code,message.content,error.contentוכן הלאה. או אם מדיניות מכסת השימוש נכשלה, אפשר להשתמש במשתנהratelimit.{quota_policy_name}.exceed.count. כדי להבין אילו משתנים ונתוני HTTP זמינים, אפשר להשתמש בכלי המעקב ובנושאי העזרה בנושא מדיניות.
מידע נוסף
-
תנאים: הפניה לתנאים ומשתני Flow ותנאים
- שגיאות: המשמעות של שגיאות שקשורות למדיניות
- משתנים: הפניה למשתנים, ודפים נפרדים של הפניות למדיניות שבהם מפורטים המשתנים שזמינים בכל מדיניות.
שיטות מומלצות לטיפול בשגיאות
טיפול בשגיאות הוא משימה חשובה בתכנון הארכיטקטורה של פיתוח proxy ל-API. חשוב להקדיש זמן כדי להבין איך ומתי לטפל בשגיאות, לקבוע מה יהיה כתוב בהודעות השגיאה ולעצב את הפורמטים של הודעות השגיאה. אחרי (או תוך כדי) שתבינו את הדברים האלה, תוכלו להשתמש בשיטות המומלצות האלה כדי ליישם את הטיפול בשגיאות.
ריכזנו כאן כמה שיטות מומלצות לעיצוב ולבנייה של טיפול בשגיאות:
- לכל FaultRule, צריך לספק
<Condition>חיצוני (באותה רמה של רכיב<Step>). כללי תקלות ללא תנאי חיצוני מוערכים אוטומטית כ-true. תנאי שלב מסוג Inner לא משמשים כדי לקבוע אם FaultRule הוא true או false. תנאי השלב מוערכים רק אחרי ש-Edge מפעיל את FaultRule שמכיל אותם. ב-FaultRule, בדרך כלל יש כמה רכיבי Step עם מדיניות Assign Message (או מדיניות אחרת), כל אחד עם תנאי לביצוע השלב. -
כדי לטפל בשגיאות בכמה מדיניות מאותו סוג (לדוגמה, כמה מדיניות של Quota), צריך ליצור FaultRule אחד לכל שגיאת מדיניות שסביר שתקבלו. לדוגמה, צריך ליצור FaultRule לכל שגיאה סבירה במדיניות בנושא מכסות, כמו
QuotaViolation,InvalidMessageWeightו-StartTimeNotSupported. (מידע על שגיאות שקשורות למדיניות זמין במאמר בנושא שגיאות שקשורות למדיניות). אם תגלו שגיאות נוספות שצריך לטפל בהן, תוכלו לחזור מאוחר יותר ולהוסיף אותן ל-FaultRules. אפשר לבצע שינויים חוזרים, אבל צריך לפרוס מחדש את ה-proxy.) הגישה הזו מאפשרת לכם לזהות את אותו סוג של שגיאה בלי קשר למדיניות שגרמה לה, וכך קובץ ה-XML של FaultRules יהיה יעיל.לאחר מכן, אפשר להשתמש בתנאים פנימיים של שלבים אם נדרשת שליטה מדויקת יותר בשגיאות. לדוגמה, אם אתם אוכפים גם מכסה לכל מפתח וגם מכסה גלובלית באמצעות שתי מדיניות בזרימת הבקשות, צריך להגדיר את התנאי של FaultRule החיצוני כך שיופעל בשגיאה
QuotaViolation(שמוחזרת כשחורגים מהמכסה בכל אחד מהמקרים). לאחר מכן מגדירים תנאים לשלב כדי להעריך את המשתניםexceed.countבשתי מדיניות המכסות. רק השגיאה הרלוונטית נשלחת ללקוח (חריגה ממכסת המפתחים או חריגה ממכסה גלובלית). דוגמה להגדרה כזו:<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>דוגמה נוספת אפשר לראות בשרשור הזה בפורום הקהילה של Apigee.
-
כדי לטפל בשגיאות כשמשתמשים במדיניות יחידה מסוג מסוים, אפשר להשתמש בכלל יחיד של תקלה שמופעל כשהמדיניות הזו נכשלת, ולכלול כמה שלבים שממופים לכל שגיאה אפשרית. כך קובץ ה-XML נשאר יעיל כי משתמשים ב-FaultRule אחד במקום בכמה FaultRule (אחד לכל סוג שגיאה). לדוגמה:
<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> - מוסיפים FaultRules במקומות שבהם השגיאות יתרחשו (בצד הלקוח
<ProxyEndpoint>או בצד היעד<TargetEndpoint>). כוללים FaultRules לכל מדיניות שמופיעה בכל מיקום. - ב-FaultRules, אפשר להפעיל כל סוג של מדיניות שיכולה להחזיר הודעה לאפליקציית הלקוח. מדיניות AssignMessage מתאימה לכך. כדאי גם לרשום הודעה ביומן באמצעות מדיניות רישום ההודעות ביומן אם רוצים לעקוב אחרי שגיאות.
- כשמשתמשים במדיניות RaiseFault בשילוב עם FaultRules, צריך לתאם את נתוני התגובה שמוחזרים כשגם מדיניות RaiseFault וגם FaultRule מחזירות נתונים. לדוגמה, אם מדיניות RaiseFault מאפסת את קוד הסטטוס של HTTP, אל תאפסו את קוד הסטטוס באמצעות FaultRule. התרחיש הכי גרוע הוא שקוד הסטטוס שמוגדר כברירת מחדל יוחזר לאפליקציית הלקוח.
-
<DefaultFaultRule>execution:- אם רוצים ש-
<DefaultFaultRule>תמיד יופעל כשלא מופעל אף FaultRule אחר, לא כוללים בו<Condition>. - אם רוצים שרכיב
<DefaultFaultRule>יפעל תמיד גם כשמופעל רכיב FaultRule אחר, מוסיפים את רכיב הצאצא<AlwaysEnforce>true</AlwaysEnforce>.
- אם רוצים ש-
תבנית לטיפול מרכזי בתקלות שאפשר לעשות בה שימוש חוזר
בפוסט הבא בקהילת Apigee מתואר דפוס לטיפול מרכזי בשגיאות ללא שכפול קוד:
דפוס לטיפול בשגיאות בשרתי proxy של Apigee
יצירת FaultRules
כדי להוסיף FaultRule, צריך לערוך את הגדרת ה-XML של ProxyEndpoint או TargetEndpoint. אפשר להשתמש בממשק המשתמש של Edge כדי לבצע את העריכה הזו בחלונית Code בתצוגה Develop של proxy ל-API, או לערוך את קובץ ה-XML שמגדיר את ProxyEndpoint או TargetEndpoint.
אם יוצרים FaultRules בממשק המשתמש לניהול, קודם יוצרים את המדיניות שרוצים להפעיל, ואז מוסיפים אותה להגדרת FaultRule. (אם תנסו לשמור FaultRule שמפנה למדיניות שעדיין לא נוצרה, תופיע שגיאה בממשק המשתמש).
הוספת מדיניות ל-FaultRule
אפשר להוסיף כל מדיניות ל-FaultRule, אבל בדרך כלל משתמשים במדיניות AssignMessage כדי ליצור הודעת תגובה מותאמת אישית למצב שגיאה. רכיב AssignMessage מאפשר לכם להגדיר תגובת HTTP עם מטען ייעודי (payload), קוד סטטוס של HTTP, כותרות ורכיבי משפט סיבה.
בדוגמה הבאה מוצגת הגדרה אופיינית של מדיניות 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>
עכשיו אפשר להשתמש במדיניות הזו ב-FaultRule. שימו לב לאופן שבו אתם מפנים למדיניות AssignMessage לפי שם ב-FaultRule:
<ProxyEndpoint name="default">
...
<FaultRules>
<FaultRule name="invalid_key_rule">
<Step>
<Name>fault_invalidkey</Name>
</Step>
<Condition>(fault.name = "InvalidApiKey")</Condition>
</FaultRule>
</FaultRules>
</ProxyEndpoint>כשפורסים את ההגדרה שלמעלה, שרת ה-proxy של ה-API יפעיל את מדיניות AssignMessage שנקראת fault_invalidkey בכל פעם שאפליקציה מציגה מפתח API לא תקין.
אפשר להפעיל כמה כללי מדיניות ב-FaultRule, כמו בדוגמה הבאה:
<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>הפעלת המדיניות מתבצעת לפי הסדר שמוגדר. לדוגמה, אפשר להשתמש במדיניות MessageLogging, במדיניות ExtractVariables, במדיניות AssignMessage או בכל מדיניות אחרת ב-FaultRule. שימו לב: העיבוד של FaultRule נפסק באופן מיידי אם מתרחש אחד מהמצבים הבאים:
- כל מדיניות ב-FaultRule גורמת לשגיאה
- אחד מכללי המדיניות ב-FaultRule הוא מסוג RaiseFault
הגדרת הודעת שגיאה מותאמת אישית שמוחזרת מ-FaultRule
מומלץ להגדיר תגובות שגיאה ברורות מממשקי ה-API. כך תוכלו לספק ללקוחות מידע עקבי ומועיל.
בדוגמה הבאה של מדיניות AssignMessage נעשה שימוש בתגים <Payload>, <StatusCode> ו-<ReasonPhase> כדי להגדיר את תגובת השגיאה המותאמת אישית שנשלחת בחזרה ללקוח בשגיאה InvalidApiKey (ראו את הדוגמה הקודמת של 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>
התשובה הזו כוללת:
- המטען הייעודי (payload) שמכיל את הודעת השגיאה וכתובת אימייל ליצירת קשר עם התמיכה.
- קוד הסטטוס של HTTP שמוחזר בתגובה.
- הסיבה, שהיא תיאור קצר של השגיאה.
יצירה של DefaultFaultRule
DefaultFaultRule פועל כרכיב handler של חריגים לכל שגיאה שלא מטופלת באופן מפורש על ידי FaultRule אחר. אם התנאים של כל ה-FaultRule לא תואמים לשגיאה, השגיאה מטופלת על ידי DefaultFaultRule. כדי להפעיל טיפול בשגיאות שמוגדר כברירת מחדל, מוסיפים את התג <DefaultFaultRule> כרכיב צאצא של ProxyEndpoint או TargetEndpoint.
לדוגמה, בהגדרת TargetEndpoint שלמטה מוגדר DefaultFaultRule שמפעיל מדיניות בשם 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>בדרך כלל משתמשים ב-DefaultFaultRule כדי להחזיר הודעת שגיאה גנרית לכל שגיאה לא צפויה, כמו הודעה שמכילה פרטים ליצירת קשר עם התמיכה הטכנית. תגובת ברירת המחדל הזו משרתת שתי מטרות: היא מספקת מידע ידידותי למפתחים וגם מסתירה כתובות URL של קצה עורפי או מידע אחר שאפשר להשתמש בו כדי לפגוע במערכת.
לדוגמה, מגדירים את מדיניות AssignMessage הבאה כדי להחזיר שגיאה כללית:
<AssignMessage name="ReturnGenericError"> <Set> <Payload type="text/plain">SERVICE UNAVAILABLE. PLEASE CONTACT SUPPORT: support@company.com.</Payload> </Set> </AssignMessage>
כדי להפעיל את DefaultFaultRule לכל שגיאה, גם אם כבר הופעל FaultRule אחר, צריך לכלול את הרכיב <AlwaysEnforce> בתג <DefaultFaultRule>. ה-DefaultFaultRule תמיד מופעל אחרון:
<DefaultFaultRule name="fault-rule">
<Step>
<Name>ReturnGenericError</Name>
</Step>
<AlwaysEnforce>true</AlwaysEnforce>
</DefaultFaultRule>אחד מהשימושים ב-DefaultFaultRule הוא לקבוע את סוג השגיאה שמתרחשת כשאין אפשרות לקבוע אותו בדרך אחרת. לדוגמה, proxy ל-API נכשל בגלל שגיאה שלא הצלחתם לזהות. משתמשים ב-DefaultFaultRule כדי להפעיל את מדיניות AssignMessage הבאה. המדיניות הזו כותבת את הערך fault.name בכותרת שנקראת DefaultFaultHeader בתגובה:
<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>
אחר כך אפשר לראות את הכותרת בכלי המעקב של Edge או בתגובה כדי להבין מה גרם לשגיאה.
הוספת רישום ביומן של הודעות ל-PostClientFlow
PostClientFlow הוא הרצף היחיד שמופעל אחרי שה-proxy עובר למצב שגיאה. אפשר לצרף לזרימה הזו רק את המדיניות MessageLogging, שמופעלת אחרי שהתשובה נשלחת בחזרה ללקוח. למרות שצירוף מדיניות MessageLogging לזרימה הזו הוא לא טיפול בשגיאות, מבחינה טכנית, אפשר להשתמש בה כדי לרשום מידע ביומן במקרה של שגיאה. היא מופעלת בלי קשר להצלחה או לכישלון של ה-proxy, ולכן אפשר להציב מדיניות של רישום הודעות ב-PostClientFlow ולהבטיח שהיא תמיד תופעל.
טיפול בתקלות שקשורות למדיניות בתהליך הנוכחי
בכל הדוגמאות שמוצגות עד עכשיו נעשה שימוש ב-FaultRule ב-ProxyEndpoint או ב-TargetEndpoint כדי לטפל בשגיאות מדיניות כחלק ממצב השגיאה. הסיבה לכך היא שערך ברירת המחדל של
האלמנט continueOnError של מדיניות הוא false, כלומר כשמתרחשת שגיאה במדיניות, השליטה מופנית למצב השגיאה. אחרי שהבקשה מגיעה למצב שגיאה, אי אפשר להחזיר את השליטה לצינור הרגיל, ובדרך כלל מוחזרת לאפליקציה ששלחה את הבקשה הודעת שגיאה כלשהי.
עם זאת, אם מגדירים את הרכיב continueOnError לערך true במדיניות, השליטה נשארת בתהליך הנוכחי והמדיניות הבאה בצינור מופעלת אחרי המדיניות שגרמה לשגיאה. היתרון בטיפול בשגיאה בתהליך הנוכחי הוא שאולי יש לך דרך לשחזר את השגיאה כדי להשלים את עיבוד הבקשה.
בדוגמה הבאה מוצגת מדיניות VerifyAPIKey בשם verify-api-key עם הרכיב continueOnError שהערך שלו הוא true:
<VerifyAPIKey async="false" continueOnError="true" enabled="true" name="verify-api-key"> <DisplayName>Verify API Key</DisplayName> <APIKey ref="request.queryparam.apikey"/> </VerifyAPIKey>
אם מפתח ה-API חסר או לא תקין, מדיניות VerifyAPIKey מגדירה את המשתנה oauthV2.verify-api-key.failed לערך true, אבל העיבוד ממשיך בתהליך הנוכחי.
לאחר מכן מוסיפים את מדיניות VerifyAPIKey כשלב ב-PreFlow של 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>שימו לב איך השלב הבא ב-PreFlow משתמש בתנאי כדי לבדוק אם קיימת שגיאה. אם התרחשה שגיאה במדיניות VerifAPIKey, המדיניות בשם
FaultInFlow policy מופעלת. אחרת, המדיניות FaultInFlow לא מופעלת. מדיניות FaultInFlow יכולה לבצע פעולות רבות, כמו רישום השגיאה ביומן, ניסיון לתקן את השגיאה או ביצוע פעולה אחרת.
הפעלת שגיאה באמצעות המדיניות RaiseFault
אפשר להשתמש במדיניות RaiseFault בכל שלב בתהליך כדי להפעיל שגיאה. כשמדיניות RaiseFault מופעלת, היא מסיימת את התהליך הנוכחי ומעבירה את השליטה למצב השגיאה.
אחד מהשימושים במדיניות RaiseFault הוא בדיקה של תנאי ספציפי שמדיניות אחרת לא יכולה לזהות. בדוגמה שלמעלה, הוספתם תג <Condition> לתג <Step> PreFlow שגרם להפעלת המדיניות FaultInFlow אם התנאי מתקיים. אם FaultInFlow היא מדיניות RaiseFault, השליטה עוברת למצב שגיאה. אפשר גם להוסיף מדיניות RaiseFault ל-Flow כדי לבצע ניפוי באגים ולבדוק את FaultRules.
כשמדיניות RaiseFault מפעילה שגיאה, אפשר להשתמש ב-FaultRule ובתנאי הבאים כדי לעבד אותה:
<FaultRule name="raisefault_rule">
<Step>
<Name>{policy_name}</Name>
</Step>
<Condition>(fault.name = "RaiseFault")</Condition>
</FaultRule>שימו לב שהתנאי בודק אם יש תקלה בשם RaiseFault. המדיניות RaiseFault
תמיד מגדירה את הערך של fault.name ל-RaiseFault.
טיפול מותאם אישית בקודי שגיאה של HTTP משרת היעד
הדוגמאות שמוצגות בקטעים הקודמים רלוונטיות לשגיאות שנוצרות על ידי כללים. אבל אפשר גם ליצור תגובה מותאמת אישית לשגיאות ברמת התעבורה, כלומר שגיאות HTTP שמוחזרות מהשרת של היעד. כדי לשלוט בתגובה משגיאת HTTP, צריך להגדיר TargetEndpoint לעיבוד קודי תגובה של HTTP.
כברירת מחדל, Edge מתייחס לקודי תגובת HTTP בטווח 1xx-3xx כאל 'הצלחה', ולקודי תגובת HTTP בטווח 4xx-5xx כאל 'כישלון'. כלומר, כל תגובה משירות ה-Backend עם קוד תגובה HTTP 4xx-5xx מפעילה באופן אוטומטי את מצב השגיאה, ואז מוחזרת הודעת שגיאה ישירות ללקוח ששלח את הבקשה.
אפשר ליצור פונקציות handler בהתאמה אישית לכל קודי תגובת HTTP. לדוגמה, יכול להיות שלא תרצו להתייחס לכל קודי התגובה של HTTP בטווח 4xx-5xx כאל 'כישלון', אלא רק לקודי 5xx, או שתרצו להחזיר הודעות שגיאה מותאמות אישית לקודי התגובה של HTTP 400 ו-500.
בדוגמה הבאה, משתמשים במאפיין success.codes כדי להגדיר את TargetEndpoint כך שיטפל בקודי תגובה מסוג HTTP 400 ו-500 כהצלחה, בנוסף לקודי ה-HTTP שמוגדרים כברירת מחדל. אם הקודים האלה נחשבים כהצלחה, TargetEndpoint משתלט על עיבוד הודעת התגובה, במקום להפעיל את מצב השגיאה:
<TargetEndpoint name="default">
...
<HTTPTargetConnection>
<Properties>
<Property name="success.codes">1xx,2xx,3xx,400,500</Property>
</Properties>
<URL>http://weather.yahooapis.com</URL>
</HTTPTargetConnection>
</TargetEndpoint>כפי שאפשר לראות בדוגמה הזו, אפשר להשתמש בתווים כלליים לחיפוש כדי להגדיר את המאפיין success.codes לטווח של ערכים.
הגדרת המאפיין success.codes מחליפה את ערכי ברירת המחדל. לכן, אם רוצים להוסיף את קוד ה-HTTP 400 לרשימת קודי ההצלחה שמוגדרים כברירת מחדל, צריך להגדיר את המאפיין הזה כך:
<Property name="success.codes">1xx,2xx,3xx,400</Property>
אבל אם רוצים שקוד HTTP 400 ייחשב כקוד הצלחה, צריך להגדיר את המאפיין כך:
<Property name="success.codes">400</Property>
עכשיו אפשר להגדיר handlers מותאמים אישית לקודי תגובת HTTP 400 ו-500 כדי להחזיר הודעת תגובה מותאמת אישית לאפליקציה ששלחה את הבקשה. ב-TargetEndpoint הבא נעשה שימוש במדיניות בשם ReturnError כדי לטפל בקודי תגובת HTTP 400 ו-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>ההגדרה הזו של TargetEndpoint גורמת לכך שהמדיניות שנקראת ReturnError תטפל בתגובה בכל פעם ש-TargetEndpoint נתקל בקוד תגובת HTTP של 400 או 500.
טקסונומיה של תקלות
שירותי API מארגנים את התקלות בקטגוריות ובקטגוריות משנה הבאות.
| קטגוריה | קטגוריית משנה | שם התקלה | תיאור |
|---|---|---|---|
| העברת הודעות | כשלים שמתרחשים במהלך זרימת ההודעות (לא כולל כשלים שקשורים למדיניות) | ||
| תקלות בהתאמה אישית | {fault_name} | תקלות שטופלו באופן מפורש על ידי proxy ל-API באמצעות מדיניות RaiseFault | |
| קודי תגובה | InternalServerError, NotFound | קודי שגיאה של HTTP 5xx, 4xx | |
| כשלים בתכנון מסלול | NoRoutesMatched | הבחירה ב-TargetEndpoint עם שם עבור בקשה נכשלה | |
| בעיות בסיווג | NotFound | כשלים שנגרמים בגלל URI של בקשה שלא תואם לאף BasePath באף הגדרה של ProxyEndpoint (כלומר, אין פרוקסי API שתואם לכתובת ה-URL בבקשה של אפליקציית הלקוח) | |
| תחבורה | שגיאות ברמת התעבורה של HTTP | ||
| קישוריות | ConnectionRefused, ConnectionReset, ConnectionTimeout | כשלים מתרחשים בזמן יצירת חיבורים ברמת הרשת או התעבורה | |
| בקשת אימותים | ContentLengthMissing, HostHeaderMissing | תקלות מתרחשות במהלך בדיקות סמנטיות בכל בקשה | |
| אימות תשובות | תקלות מתרחשות במהלך בדיקות סמנטיות בכל תגובה | ||
| שגיאות IO | SSLHandshakeError, ReadTimeout, ReadError, WriteTimeout, WriteError, ChunkError | שגיאות קריאה/כתיבה בנקודות קצה של לקוח או יעד, פסק זמן, שגיאות TLS/SSL ושגיאות חלוקה למקטעים | |
| מערכת | שגיאות לא מוגדרות בזמן הריצה | ||
| זיכרון | OutOfMemory, GCOverLimit | כשלים שקשורים לזיכרון | |
| חוט תפירה | RogueTaskTerminated | כשלים כמו סיום של משימות שחורגות מהזמן שהוקצב להן | |
| מדיניות | התקלות בכל סוג מדיניות מוגדרות בחומר העזר בנושא מדיניות. | ||
לכל שגיאה מצורף תיאור טקסט של הסיבה לכישלון. כשהמערכת מעלה תקלה, קבוצה של מאפיינים מאוכלסת כדי לעזור בפתרון הבעיה. תקלה כוללת את הפרטים הבאים:
- סיבה
- מאפיינים מותאמים אישית שהוגדרו על ידי המשתמש
