טיפול בכשלים

כרגע מוצג התיעוד של Apigee Edge.
נכנסים למסמכי התיעוד של Apigee X.
מידע

הרבה מצבי שגיאה עשויים להיווצר בזמן ששרתי proxy של ה-API מעניקים שירות לבקשות מאפליקציות. לדוגמה, שרתי proxy של API עשויים להיתקל בבעיות ברשת במהלך התקשורת עם שירותים לקצה העורפי, אפליקציות עשויות להציג פרטי כניסה שפג תוקפם, שהודעות הבקשה עשויות להיות בפורמט שגוי וכו'.

כשמתרחשת שגיאה אחרי שאפליקציית לקוח קוראת לשרת proxy של API, מוחזרת הודעת שגיאה ללקוח. כברירת מחדל, הלקוח מקבל בדרך כלל הודעת שגיאה מוצפנת ללא פרטים או הנחיות. עם זאת, כדי להחליף את הודעות השגיאה המוגדרות כברירת מחדל בהודעות מותאמות אישית שימושיות יותר, ואפילו להעשיר אותן בדברים כמו כותרות HTTP נוספות, צריך להגדיר טיפול מותאם אישית בשגיאות ב-Edge.

טיפול מותאם אישית בשגיאות גם מאפשר להוסיף פונקציות, כמו רישום הודעות ביומן, בכל פעם שמתרחשת שגיאה.

לפני שנדבר על הטמעת טיפול מותאם אישית בשגיאות בשרתי ה-API שלכם, מומלץ להבין איך מתרחשות שגיאות ואיך שרתי ה-API של ה-API מגיבים אליהן.

סרטונים

בסרטונים הבאים אפשר לקבל מידע נוסף על טיפול בפגמים.

וידאו תיאור
מבוא לטיפול בשגיאות ותהליכי עבודה בשגיאות מידע על טיפול בשגיאות ומה קורה כשמתרחשת שגיאה בשרת proxy ל-API.
טיפול בשגיאות באמצעות כללי שגיאות לומדים איך לטפל בשגיאות באמצעות כללי שגיאות.
מעלים שגיאות בהתאמה אישית באמצעות מדיניות RaiseFault אפשר להעלות שגיאות בהתאמה אישית בזמן הריצה של ה-API באמצעות מדיניות RaiseFault.
הגדרת כללי כשלים בשרת proxy ל-API ובנקודות הקצה (endpoint) של היעד צריך להגדיר כללי תקלות בשרת ה-API של ה-API ונקודות הקצה לטירגוט, ולהבין את ההבדלים.
הסבר על סדר הביצוע של כללי השגיאות הסבר על סדר הביצוע של כללי השגיאה בשרת ה-API ובנקודות הקצה (endpoint) של היעד.
הגדרה של כלל ברירת המחדל לכשל יש להגדיר כלל ברירת מחדל לטיפול בשגיאות כלליות ב-API.

איך מתרחשות השגיאות

תחילה נסביר איך מתרחשות שגיאות איך. כשיודעים איך מתרחשות שגיאות, אפשר לתכנן למצבים השונים שבהם רוצים להטמיע טיפול מותאם אישית בשגיאות.

שגיאות אוטומטיות

שרת proxy ל-API גורם לשגיאה באופן אוטומטי במצבים הבאים:

  • מדיניות גורמת לשגיאה. לדוגמה, אם קריאה ל-API שולחת מפתח שפג תוקפו, מדיניות VerifyAPIKey גורמת באופן אוטומטי להצגת שגיאה. אם מספר הקריאות ל-API חורג ממגבלה מסוימת, מדיניות המכסה או מדיניות SpikeArrest גורמות להצגת הודעת שגיאה. (בחומר העזר בנושא שגיאות מדיניות) אפשר למצוא את סוגי השגיאות שיכולים לגרום למדיניות.
  • יש בעיה בתהליך ההודעות של שרת ה-API של שרת ה-API, למשל שגיאה בניתוב.
  • יש כשל בקצה עורפי, למשל שגיאת HTTP עקב כשלים ברמת הפרוטוקול, שגיאות TLS/SSL או שירות יעד לא זמין.
  • מדובר בכשל ברמת המערכת, למשל חריגה ממגבלת הזיכרון.

למידע נוסף על השגיאות האלה, ניתן לעיין בנושא טקסונומיית תקלות.

שגיאות בהתאמה אישית

במצבים שבהם אין שגיאה אוטומטית, ייתכן שתרצו להקפיץ שגיאה מותאמת אישית. לדוגמה, אם תגובה מכילה את המילה "unavailable", או אם קוד המצב של HTTP גדול מ-201. כדי לעשות את זה, מוסיפים RaiseFault מדיניות למקום המתאים בתהליך של שרת ה-proxy של ה-API.

אפשר להוסיף מדיניות RaiseFault לזרימת שרת proxy של API באותו אופן שבו עושים כל מדיניות אחרת. בדוגמה הבאה של הגדרת שרת proxy, המדיניות Raise-Fault-1 מצורפת לתגובה של TargetEndpoint. אם המילה "un available" (לא זמין) מופיעה בתגובה משירות היעד, המדיניות RaiseFault מופעלת וגורמת שגיאה.

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

המטרה היא רק להראות שאפשר למחוק שגיאות בהתאמה אישית. אנחנו מפרטים פרטים נוספים על המדיניות של RaiseFault בקטע Fault Rules vs. RaiseFault.

דוגמאות נוספות לפוסטים הבאים בפורומים של קהילת Apigee:

מה שרתי proxy של API עושים כשמתרחשות שגיאות

זה מה שקורה כאשר שרת proxy גורם הודעת שגיאה.

יציאה מצינור עיבוד הנתונים של שרת ה-proxy

כששרת proxy ל-API נתקל בשגיאה, לא משנה איך היא מתרחשת, הוא יוצא מצינור עיבוד הנתונים הרגיל, נכנס למצב שגיאה ומחזיר הודעת שגיאה לאפליקציית הלקוח. אחרי ששרת ה-API של ה-API נכנס למצב השגיאה, הוא לא יכול להחזיר את העיבוד לצינור עיבוד הנתונים הרגיל.

לדוגמה, נניח שלשרת proxy ל-API יש כללי מדיניות בסדר הבא בבקשת ProxyEndpoint:

  1. אימות מפתח API
  2. מכסה
  3. JSON ל-XML

אם מתרחשת שגיאה במהלך האימות של מפתח API, שרת ה-API של ה-API עובר למצב שגיאה. המדיניות לגבי מכסות ו-JSON ל-XML לא מופעלת, שרת ה-proxy לא ממשיך לנקודת היעד ומוחזר הודעת שגיאה לאפליקציית הלקוח.

חיפוש כללי שגיאות

במצב השגיאה, שרתי proxy של ה-API בודקים גם אם קיימים הפריטים הבאים (לפי הסדר) בהגדרה של שרת ה-API של ממשק ה-API, לפני החזרת הודעת שגיאה המוגדרת כברירת מחדל לאפליקציית הלקוח:

  1. קטע <FaultRules>, שמכיל את הלוגיקה להפעלת הודעות שגיאה מותאמות אישית (וכללי מדיניות אחרים) על סמך תנאים ספציפיים שאתם מגדירים.
  2. קטע <DefaultFaultRule>, שמפעיל הודעת שגיאה שמוגדרת כברירת מחדל במצבים הבאים:
    • לא הוגדרו <FaultRules>.
    • לא בוצעה הפעלה של <FaultRules> קיימים.
    • הרכיב <AlwaysEnforce> מוגדר כ-True.

למעשה, שרת ה-proxy של ה-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, כדי להגדיר מטען ייעודי (payload) וכותרות HTTP אופציונליות, כמו קוד סטטוס וביטוי סיבה. השיטה 'הקצאת הודעה' מתאימה במיוחד למטרה הזו. היא מאפשרת לשלוט במטען הייעודי (payload) של הודעות, להגדיר קוד מצב HTTP שונה, להגדיר ביטוי אחר לסיבת ה-HTTP ולהוסיף כותרות HTTP.

אין לצרף את המדיניות לתהליך כלשהו בשרת ה-API של שרת ה-proxy. מספיק שהוא פשוט קיים בחבילת ה-proxy. כדי לעשות זאת בעורך ה-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> כדי לספק הודעת שגיאה כללית בהתאמה אישית אם לא הופעל אף אחד מכללי ה-Fault Rules.

דוגמה

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

נקודות עיקריות:

  • כללי הכשלים מוגדרים ב-ProxyEndpoint. זה חשוב. מידע נוסף על הוספה של כללי Fault ל-ProxyEndpoint ול-TargetEndpoint מאוחר יותר
  • <Name> – שם המדיניות להפעלה. השם מגיע ממאפיין המדיניות name ברכיב ההורה, כפי שמוצג בדוגמת המדיניות הקודמת.
  • <Condition> – Edge בודקת את התנאי ומפעילה את המדיניות רק אם התנאי מתקיים. אם יש כמה כללי Fault שמעריכים את הערך True, המערכת של Edge מפעילה את הכלל הראשון שמתקיים. (חשוב: הסדר שבו מתבצעת הערכה של כללי ה-Fault Rules, מלמעלה למטה או מלמטה עד למעלה, שונה בין TargetEndpoint ו-ProxyEndpoint, כפי שמתואר בקטע Multiple Fault Rules and בלי בשבילכם לפעול.) אם לא מציינים תנאי, ה-FaultRule מתקיים באופן אוטומטי. אבל זו לא שיטה מומלצת. לכל FaultRule צריך להיות תנאי משלו.

  • <DefaultFaultRule> - אם לא מופעל FaultRule מותאם אישית, הפקודה <DefaultFaultRule> מופעלת, ושולח הודעה מותאמת אישית כללית יותר במקום ההודעה המוצפנת שנוצרה כברירת מחדל על ידי Edge. <DefaultFaultRule> יכול לכלול גם <Condition>, אבל ברוב המקרים לא כוללים אותו כי רוצים שהוא יופעל, לא משנה מה יש בתור מוצא אחרון.

    השדה DefaultFaultRule משמש בדרך כלל כדי להחזיר הודעת שגיאה כללית על כל שגיאה לא צפויה. לדוגמה, הודעה עם פרטים ליצירת קשר עם צוות התמיכה הטכנית. תגובת ברירת המחדל הזו משמשת גם למטרה כפולה של מתן מידע ידידותי למפתחים, תוך ערפול כתובות URL בקצה העורפי או מידע אחר שעלול לשמש לפגיעה במערכת.

כללי שגיאות מרובים ולוגיקת ביצוע

בקטע דוגמה לטיפול פשוט בכשלים, השתמשנו בדוגמה פשוטה ל-FaultRule ולתנאי יחיד. בפרויקט API בעולם האמיתי, עם כל השגיאות האפשריות, סביר להניח שיהיו מספר Fault Rules ו-DefaultFaultRule גם ב-<ProxyEndpoint> וגם ב-<TargetEndpoint>. אבל בסופו של דבר, רק FaultRule אחד מבוצע כששרת proxy של API עובר למצב שגיאה.

בקטע הזה מתואר הלוגיקה שבה משתמש Edge במהלך הטיפול ב-Fault Rules, החל מהאופן שבו הוא מגיע ל-FaultRule יחיד לביצוע ועד לאופן שבו תנאים של שלב "פנימי" מטופלים כאשר FaultRule מופעל. בקטע הזה מפורטות גם הנחיות לגבי מתי להגדיר כללי Fault ב-<ProxyEndpoint> לעומת <TargetEndpoint>, ומתאר את הקשר בין Fault Rules והמדיניות UploadFault.

ביצוע כללי שגיאות

בקיצור, זהו הלוגיקה של Edge כאשר שרת proxy של API עובר למצב שגיאה. חשוב לזכור שיש הבדל קטן בין ההערכה של Fault Rules ב-ProxyEndpoint לבין ההערכה של TargetEndpoint.

  1. שירות Edge בודק את כללי ה-Fault פגישה עם ProxyEndpoint או TargetEndpoint, בהתאם למקום שבו אירעה השגיאה:
    • ProxyEndpoint – Edge מתחיל ב-<FaultRule> התחתון ב-XML של ההגדרה ופועלת כלפי מעלה, תוך הערכה של ה<Condition> של כל <FaultRule> (התנאי ה "חיצוני", ולא התנאים ה "פנימיים" <Step>).
    • TargetEndpoint – Edge מתחיל ב-<FaultRule> העליון ב-XML של ההגדרה ופועלת כלפי מטה, תוך הערכה של ה-<Condition> של כל <FaultRule> (התנאי ה "חיצוני", ולא התנאים ה "פנימיים" <Step>).
  2. מפעיל את FaultRule הראשון שהתנאי שלו מתקיים. אם ב-FaultRule אין תנאי, הוא מוגדר כברירת מחדל.
    • כשמבצעים FaultRule, כל השלבים שבתוך FaultRule נבדקים לפי הסדר, מלמעלה למטה בתצורת ה-XML. שלבים ללא תנאים מבוצעים באופן אוטומטי (המדיניות מתבצעת), ושלבים שיש להם <Condition> שהערך שלהם הוא "true" מבוצעים (תנאים עם הערך "false" לא מבוצעים).
    • אם FaultRule מופעל, אבל לא מבוצעים שלבים ב-FaultRule (כי התנאים שלהם מקבלים את הערך "false"), הודעת השגיאה שהוגדרה כברירת מחדל שנוצרה באמצעות Edge מוחזרת לאפליקציית הלקוח. <DefaultFaultRule> לא מופעל, כי Edge כבר ביצע FaultRule אחד.

  3. אם לא מופעל FaultRule, אפליקציית Edge מבצעת את <DefaultFaultRule>, אם היא קיימת.

בהמשך מופיעות דוגמאות עם תגובות בתוך השורה.

ביצוע של ProxyEndpoint

ההערכה של ProxyEndpoint Fault Rules היא מלמטה, לכן מומלץ להתחיל לקרוא ב-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 Fault Rules מתבצעת מלמעלה למטה. לכן, מומלץ להתחיל לקרוא ב-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>

סדר כללי התקלה

כמו שאפשר לראות בדוגמה הקודמת, הסדר שבו קבעת את כללי ה-Fault הוא חשוב בהתאם לשגיאה שבה מתרחשת השגיאה ב-ProxyEndpoint לעומת המצב ב-TargetEndpoint.

לדוגמה:

הזמנה של ProxyEndpoint הזמנה של נקודת קצה (Targetendpoint)

בדוגמה הבאה, מכיוון שההערכה מלמטה למעלה, מתבצעת הפעלה של FaultRule 3, ולכן לא מתבצעת הערכה של Fault Rules 2 ו-1.

5. FaultRule 1: FALSE

4. FaultRule 2: TRUE

3. FaultRule 3: TRUE

2. FaultRule 4: FALSE

1. FaultRule: 5 FALSE

בדוגמה הבאה, מאחר שההערכה היא מלמעלה למטה, מתבצעת הפעלה של FaultRule 2, ולכן לא מתבצעת הערכה של Fault Rules 3, 4 ו-5.

1. FaultRule 1: FALSE

2. FaultRule 2: TRUE

3. FaultRule 3: TRUE

4. FaultRule 4: FALSE

5. FaultRule: 5 FALSE

כללי מדיניות שיש לכלול

אפשר לבצע כל מדיניות מ-FaultRule על ידי העברתם ל'שלבים'. לדוגמה, אפשר להפעיל מדיניות AssignMessage כדי לעצב תשובה לאפליקציית הלקוח, ולאחר מכן לרשום הודעה באמצעות המדיניות MessageLogging. כללי המדיניות מבוצעים לפי הסדר שבו הוגדרו (מלמעלה למטה ב-XML).

כללי שגיאה מופעלים רק במצב שגיאה (about continueOnError)

יכול להיות שהכותרת נראית כמו שאנחנו חוזרים על עצמנו, אבל יש ניואנסים ספציפיים שצריך לשים לב אליהם לגבי שגיאה בשרת proxy שגורמת לשרת proxy של API להיכנס למצב שגיאה – או לא להזין מצב שגיאה: המאפיין continueOnError במדיניות.

לסיכום: שרת proxy של API מבצע הערכה של <FaultRules> ו-<DefaultFaultRule> רק אם שרת ה-proxy נכנס למצב שגיאה. כלומר, גם אם תנאי FaultRule מקבל הערכה לערך True, הוא לא יופעל אם שרת ה-proxy לא במצב שגיאה.

עם זאת, הנה דוגמה לשגיאה שמתרחשת ושרת ה-proxy לא נכנס למצב שגיאה. בכל מדיניות אפשר להגדיר מאפיין ברכיב ההורה שנקרא continueOnError. המאפיין הזה חשוב מאוד לטיפול בכשלים, כי הוא קובע אם שרת ה-proxy יכנס למצב שגיאה אם המדיניות תיכשל. ברוב המקרים, כדאי להשאיר את ברירת המחדל continueOnError="false". כך שרת ה-proxy יעבור למצב שגיאה אם המדיניות תיכשל והטיפול בשגיאות בהתאמה אישית יופעל. עם זאת, אם continueOnError="true" (לדוגמה, אם אינך רוצה שהסבר על השירות יעצור את ההפעלה של שרת ה-proxy), שרת ה-proxy לא יעבור למצב שגיאה אם המדיניות הזו תיכשל, ושרת ה-proxy לא יבדוק את כללי ה-Fault Rules.

אפשר לקרוא מידע על רישום שגיאות ברישום ביומן במהלך continueOnError="true" במאמר טיפול בשגיאות של מדיניות בתהליך הנוכחי.

איפה מגדירים Fault Rules: ProxyEndpoint או TargetEndpoint

כשיש שגיאה בשרת proxy של API, השגיאה מתרחשת ב-<ProxyEndpoint> (בקשה מאפליקציית הלקוח או תגובה לאפליקציית הלקוח) או ב-<TargetEndpoint> (בקשה לשירות או תגובה משירות היעד). בכל מקום שבו מתרחשת השגיאה הזו, Edge מחפש את כללי Fault Rules.

לדוגמה, אם שרת יעד אינו זמין (קוד סטטוס HTTP 503), שרת ה-API של ה-API ייכנס למצב שגיאה בתגובת <TargetEndpoint>, והזרימה הרגילה של שרת ה-proxy של ה-API לא תמשיך אל <ProxyEndpoint>. אם הגדרת כללי תקלות רק ב-<ProxyEndpoint>, הם לא יטפלו בשגיאה הזו.

כאן יש דוגמה נוספת. אם מדיניות RaiseFault בתגובה <ProxyEndpoint> גורמת לשגיאה, לא תתבצע הפעלה של FaultRule ב-<TargetEndpoint>.

כללי תקלות לעומת מדיניות 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 עבור כללי מדיניות שונים. עבור מרחבי שמות של מדיניות, ניתן לעיין במשתני הזרימה בכל נושא חומר עזר בנושא מדיניות.

משתנים זמינים נוספים

כששרת proxy של API עובר למצב שגיאה, המשתנים היחידים שאפשר להשתמש בהם בתנאים הם:

  • המשתנים של המדיניות שנכשלו.
  • המשתנים של הודעת ה-HTTP שקיימים בזמן הכשל. לדוגמה, אם מתקבלת שגיאה בתגובה, FaultRule ב-<TargetEndpoint> יכול להשתמש בנתוני ה-HTTP response.status.code, message.content, error.content וכן הלאה. אם הקריטריון Quota policy נכשל, אפשר להשתמש במשתנה ratelimit.{quota_policy_name}.exceed.count. אפשר להשתמש בכלי המעקב ובנושאי הפנייה למדיניות כדי לבדוק אילו משתנים ונתוני HTTP זמינים.

מידע נוסף

שיטות מומלצות לטיפול בשגיאות

טיפול בפגמים הוא משימה משמעותית של תכנון ארכיטקטוני לצורך פיתוח של שרתי proxy ל-API. חשוב להקדיש זמן כדי להבין איך ומתי לטפל בשגיאות, לקבוע מה יופיע בהודעות השגיאה ולעצב את הפורמטים של הודעות השגיאה. אחרי (או בזמן) שמבינים את הדברים האלה, כדאי להשתמש בשיטות המומלצות האלה כדי לפתור בעיות בהטמעה.

בהמשך מפורטות כמה שיטות מומלצות לתכנון ולטיפול בפגמים:

  • לכל FaultRule, יש לציין <Condition> "חיצוני" (כמו כן לרכיב <Step>). כללי שגיאה ללא תנאי חיצוני מעריכים באופן אוטומטי את הערך True. תנאים מסוג "שלב פנימי" לא משמשים כדי לקבוע אם FaultRule הוא נכון או לא נכון. תנאי השלבים נבדקים רק אחרי ש-Edge מבצע את ה-FaultRule שמכיל אותם. ב-FaultRule, בדרך כלל יש מספר שלבים עם כללי מדיניות של הקצאת הודעה (או מדיניות אחרת), שבכל אחד מהם יש תנאי של שלב.
  • כדי לטפל בשגיאות בכמה כללי מדיניות מאותו סוג (לדוגמה, כמה כללי מדיניות Quota), צריך ליצור FaultRule אחד לכל שגיאת מדיניות שאתם צפויים לקבל. לדוגמה, יוצרים FaultRule לכל שגיאה סבירה במדיניות המכסה, למשל QuotaViolation, InvalidMessageWeight, StartTimeNotSupported. (אפשר למצוא מידע על שגיאות מדיניות בחומר העזר בנושא שגיאות מדיניות. כשגילינו שגיאות נוספות שצריך לטפל בהן, אפשר לחזור מאוחר יותר ולהוסיף אותן לכללי ה-Fault Rules. זה בסדר לחזור על שלבים, אבל זה מצריך פריסה מחדש של שרת ה-proxy.) הגישה הזו מאפשרת לזהות את אותו סוג של שגיאות בלי קשר למדיניות שמובילה אליהן, וכך לייעל את קובץ ה-XML של Fault Rules.

    אם אתם צריכים בקרת שגיאות פרטנית יותר, השתמשו בתנאי השלב הפנימי. לדוגמה, אם בחרת לאכוף גם מכסת מפתחים אישית וגם מכסה גלובלית עם שני כללי מדיניות בתהליך הבקשה שלך, עליך להגדיר את התנאי "outer" 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 יחיד, במקום מספר כללי Fault (אחד לכל סוג שגיאה). לדוגמה:

    <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>
    
  • יש להוסיף כללי כשלים שבהם השגיאות יתרחשו (צד הלקוח <ProxyEndpoint> או צד היעד <TargetEndpoint>). צריך לכלול כללי תקלות לכל מדיניות שמופיעה בכל מיקום.
  • ב-Fault Rules, אפשר להפעיל כל סוג של מדיניות שיכולה להחזיר הודעה לאפליקציית הלקוח. המדיניות של AssignMessage במקרה הזה מתאימה במיוחד. בנוסף, אם ברצונך לעקוב אחרי שגיאות, מומלץ לרשום הודעות באמצעות מדיניות MessageLogging.
  • כשמשתמשים במדיניות RaiseFault בשילוב עם Fault Rules, צריך לתאם את נתוני התגובות שנשלחים בחזרה כאשר הם: מדיניות RaiseFault, וגם נתוני החזרה של FaultRule. לדוגמה, אם המדיניות RaiseFault מאפסת את קוד הסטטוס של HTTP, אין לבצע FaultRule שמאפס את קוד הסטטוס. הדבר הגרוע ביותר שיכול לקרות הוא שקוד הסטטוס המוגדר כברירת מחדל מוחזר לאפליקציית הלקוח.
  • ביצוע של <DefaultFaultRule>:
    • אם רוצים ש-<DefaultFaultRule> יופעל תמיד כשלא מופעל FaultRule אחר, אין לכלול בו <Condition>.
    • אם רוצים ש-<DefaultFaultRule> יופעל תמיד גם כשבוצעה FaultRule אחר, יש להוסיף את אלמנט הצאצא <AlwaysEnforce>true</AlwaysEnforce>.

תבנית לטיפול בשגיאות מרוכזות וניתנות לשימוש חוזר

בפוסט הבא של קהילת Apigee מתואר דפוס לטיפול בשגיאות מרוכזות ללא שכפול קוד:

https://community.apigee.com/articles/23724/an-error-handling-pattern-for-apigee-proxies.html

יצירת כללי שגיאות

כדי להוסיף FaultRule, צריך לערוך את הגדרת ה-XML של ProxyEndpoint או TargetEndpoint. אפשר להשתמש בממשק המשתמש של Edge כדי לבצע את העריכה הזו בחלונית Code (קוד) בתצוגה פיתוח עבור שרת proxy ל-API, או לערוך את קובץ ה-XML שמגדיר את ProxyEndpoint או TargetEndpoint.

אם יוצרים Fault Rules בממשק המשתמש לניהול, קודם צריך ליצור את כללי המדיניות שרוצים להפעיל, ואז להוסיף אותם להגדרת 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>

כשפורסים את ההגדרה שלמעלה, שרת ה-API של ה-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 (ניתן לעיין בדוגמה הקודמת של Fault Rules).

<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 אחר. אם התנאים בכל ה-Fault Rules לא תואמים לשגיאה, הערך של 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>

יש לכלול את הרכיב <AlwaysEnforce> בתג <DefaultFaultRule> כדי להפעיל את DefaultFaultRule עבור כל שגיאה, גם אם כבר בוצעה FaultRule אחר. DefaultFaultRule הוא תמיד ה-FaultRule האחרון שצריך לבצע:

  <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 הצליח או נכשל, אפשר להגדיר את המדיניות של Message Logging ב-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, אבל העיבוד ממשיך בתהליך הנוכחי.

לאחר מכן צריך להוסיף את מדיניות ValidAPIKey כשלב ב-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 תבוצע. אחרת, המערכת תדלג על המדיניות FaultInFlow. באמצעות המדיניות FaultInFlow אפשר לבצע הרבה פעולות, כמו רישום השגיאה, ניסיון לתקן את השגיאה או ביצוע פעולה אחרת.

הפעלת שגיאה באמצעות מדיניות RaiseFault

אתם יכולים להשתמש במדיניות RaiseFault בכל שלב בתהליך כדי לגרום לשגיאה. כשמופעלת מדיניות RaiseFault, היא מסיימת את התהליך הנוכחי ומעבירה את הבקרה למצב השגיאה.

אחד השימושים במדיניות RaiseFault הוא לבדוק תנאי ספציפי שייתכן שמדיניות אחרת לא תזהה. בדוגמה שלמעלה, הוספת תג <Condition> לתג PreFlow <Step>, שגרם למדיניות FaultInFlow לפעול אם התנאי מתקיים. אם המדיניות FaultInFlow היא RaiseFault, אפשר לקבוע העברות למצב השגיאה. לחלופין, אפשר להוסיף מדיניות RaiseFault בתהליך כדי לנפות באגים ולבדוק את כללי Fault Rules.

כשמדיניות 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 כ-'failure'. כלומר, כל תגובה מהשירות לקצה העורפי עם קוד תגובת HTTP 4xx-5xx מפעילה באופן אוטומטי את מצב השגיאה, ואז מחזירה הודעת שגיאה ישירות ללקוח המבקש.

אפשר ליצור רכיבי handler בהתאמה אישית לכל קוד תגובה של HTTP. לדוגמה, ייתכן שלא תרצו להתייחס לכל קודי התגובות של HTTP בטווח 4xx-5xx כ 'נכשל' אלא רק ל-5xx. לחלופין, יכול להיות שתרצו להחזיר הודעות שגיאה מותאמות אישית עבור קודי תגובה 400 ו-500 של HTTP.

בדוגמה הבאה, משתמשים במאפיין 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>

כמו שאפשר לראות בדוגמה הזו, אפשר להשתמש בתווים כלליים לחיפוש כדי להגדיר את המאפיין percent.codes לטווח ערכים.

הגדרה של המאפיין Success.codes תחליף את ערכי ברירת המחדל. לכן, אם אתם רוצים להוסיף קוד HTTP 400 לרשימת קודי ההצלחה שמוגדרים כברירת מחדל, צריך להגדיר את הנכס הזה כך:

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

אבל אם רוצים שיטופל רק קוד HTTP 400 כקוד הצלחה, יש להגדיר את המאפיין כך:

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

עכשיו אפשר להגדיר רכיבי handler בהתאמה אישית לקודי תגובה 400 ו-500 של HTTP, כדי להחזיר הודעת תגובה מותאמת אישית לאפליקציה המבקשת. ה-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, לא נמצא קודי שגיאת HTTP 5xx, 4xx
כשלים בניתוב לא נמצאו מסלולים תואמים כשל בבחירת TargetEndpoint בשם לבקשה
כשלים בסיווג לא נמצא כשלים שנגרמו על ידי URI של בקשה שלא תואם לאף BasePath בהגדרות של ProxyEndpoint (כלומר, אין שרתי proxy של API שתואמים לכתובת ה-URL בבקשה של אפליקציית הלקוח)
תחבורה שגיאות ברמת ההעברה של HTTP
קישוריות ConnectionRefused, ConnectionReset, ConnectionTimeout יש כשלים בעת יצירת חיבורים ברמת הרשת או ברמת התעבורה
אימותים של בקשות ContentLengthחסר, HostHeader missing שגיאות מתרחשות במהלך בדיקות סמנטיקה של כל בקשה
אימותים של תשובות שגיאות מתרחשות במהלך בדיקות סמנטיקה של כל תגובה
שגיאות IO SSLHandshakeError, ReadTimeout, ReadError, WriteTimeout, WriteError, chunkError שגיאות קריאה/כתיבה בלקוח או בנקודות הקצה (endpoints), זמן קצוב לתפוגה, שגיאות TLS/SSL ושגיאות מקטעים
מערכת שגיאות זמן ריצה לא מוגדרות
זיכרון OutOfMemory, GCOverLimit כשלים שקשורים לזיכרון
Thread המשימה הזדונית בוטלה כשלים כמו סיום משימות מסוג 'התחמקות'
מדיניות שגיאות בכל סוג מדיניות מוגדרות בחומר העזר בנושא מדיניות.

שגיאה תמיד נלווה בטקסט תיאור של הסיבה לכשל. כשהמערכת מזהה שגיאה, מאוכלסת קבוצת מאפיינים כדי לסייע בפתרון בעיות. תקלה כוללת את הפרטים הבאים:

  • הסיבה
  • מאפיינים מותאמים אישית שהוגדרו על ידי המשתמש