טיפול בכשלים

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

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

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

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

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

סרטונים

למידע נוסף על טיפול בפגמים, מומלץ לצפות בסרטונים הבאים.

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

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

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

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

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

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

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

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

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

אפשר להוסיף מדיניות 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:

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

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

חיפוש כללי תקלות

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

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

דוגמה

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

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

  • כללי ה-Fault{6} מוגדרים ב-ProxyEndpoint. זה חשוב. בהמשך אפשר לקרוא מידע נוסף על הוספת כללי Fault ל-ProxyEndpoint לעומת TargetEndpoint.
  • <Name> - שם המדיניות להפעלה. השם מגיע ממאפיין name של המדיניות ברכיב ההורה, כפי שמוצג בדוגמה הקודמת של המדיניות.
  • <Condition> – מערכת Edge מודדת את התנאי ומפעילה את המדיניות רק אם התנאי מתקיים. אם יש כמה כללי Fault Rules שערך 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 Rules ב-<ProxyEndpoint> לעומת <TargetEndpoint>, ותוארו גם הקשר בין Fault Rules ו-RaiseFault.

ביצוע כללי תקלות

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

  1. המערכת של Edge מבצעת הערכה של כללי ה-Fault Rules ב-ProxyEndpoint או ב-TargetEndpoint, בהתאם למקום שבו קרתה השגיאה:
    • ProxyEndpoint – Edge מתחיל בתחתית <FaultRule> בתצורת ה-XML ופועל למעלה, תוך הערכה של ה-<Condition> של כל <FaultRule> (התנאי 'החוצה', ולא התנאים ה'פנימיים' <Step>).
    • TargetEndpoint – Edge מתחיל ב-<FaultRule> העליון ב-XML של התצורה ופועל למטה, תוך הערכה של ה-<Condition> של כל <FaultRule> (התנאי "החיצוני", ולא התנאים "הפנימיים" <Step>).
  2. מפעיל את ה-FaultRule הראשון שהתנאי שלו מתקיים. אם ל-FaultRule אין תנאי, הוא TRUE כברירת מחדל.
    • כשמתבצע 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

ההערכה של 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>

סדר כלל שבר

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

לדוגמה:

הזמנה של ProxyEndpoint הזמנה של TargetEndpoint

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

5. FaultRule 1: FALSE

4. תקלה 2: TRUE

3. תקלה 3: TRUE

2. FaultRule 4: FALSE

1. FaultRule: 5 FALSE

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

1. FaultRule 1: FALSE

2. תקלה 2: TRUE

3. תקלה 3: TRUE

4. FaultRule 4: FALSE

5. FaultRule: 5 FALSE

כללי המדיניות שצריך לכלול

אפשר להוציא לפועל כל מדיניות מ-FaultRule על ידי הוספה שלה ל'שלבים'. לדוגמה, אפשר להריץ מדיניות הקצאה של הודעה כדי לעצב תשובה לאפליקציית הלקוח, ואז לרשום הודעה באמצעות המדיניות 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.

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

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

Fault Rules לעומת מדיניות RaiseFault

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

בקצרה:

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

    לדוגמה, אם רוצים להציג הודעת שגיאה אם קוד הסטטוס של HTTP בתגובה של שירות היעד גדול מ-200, מוסיפים מדיניות UploadFault בתהליך התגובה. כתוב האתר שלך תיראה כך:

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

    לאחר מכן, אם אתם צריכים בקרת שגיאות מדויקת יותר, השתמשו בתנאי השלב הפנימי. לדוגמה, אם אתם אוכפים גם מכסה למפתחים וגם מכסה גלובלית באמצעות שני כללי מדיניות בתהליך הבקשה, צריך להגדיר את התנאי "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 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>
    
  • צריך להוסיף כללי Fault Rules שבהם השגיאות יתרחשו (צד הלקוח <ProxyEndpoint> או צד היעד <TargetEndpoint>). צריך לכלול כללי Fault Rules לכל מדיניות שמופיעה בכל מיקום.
  • ב-Fault Rules, אפשר להוציא לפועל כל סוג של מדיניות שיכולה להחזיר הודעה לאפליקציית הלקוח. המדיניות של assignMessage מתאימה במיוחד למטרה הזו. בנוסף, מומלץ להשתמש במדיניות MessageLogging כדי לעקוב אחר שגיאות.
  • כשמשתמשים במדיניות RaiseFault בשילוב עם FaultRules, צריך לתאם את נתוני התגובות שנשלחים בחזרה כשהמדיניות של 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 או היעד. אפשר להשתמש בממשק המשתמש של Edge כדי לבצע את העריכה הזו בחלונית Code שבתצוגה המפורטת Develop (פיתוח) עבור שרת proxy ל-API, או לערוך את קובץ ה-XML שמגדיר את ProxyEndpoint או TargetEndpoint.

אם יוצרים FaultRules בממשק המשתמש, צריך קודם ליצור את כללי המדיניות שרוצים ליישם ואז להוסיף אותם להגדרות של FaultRule. (אם תנסו לשמור FaultRule שמפנה למדיניות שעדיין לא נוצרה, תופיע שגיאה בממשק המשתמש).

הוספת כללי מדיניות ל-FaultRule

אפשר לכלול כל מדיניות ב-FaultRule, אבל בדרך כלל משתמשים במדיניות AssignedMessage כדי ליצור הודעת תגובה מותאמת אישית לתנאי שגיאה. assignMessage מאפשר לך להגדיר תגובת HTTP עם מטען ייעודי (payload), קוד מצב HTTP, כותרות ורכיבים של ביטוי סיבה.

הדוגמה הבאה ממחישה הגדרה אופיינית של מדיניות הקצאה:

<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, המדיניות החלוצים, המדיניות של 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>

התשובה הזו כוללת את הפרטים הבאים:

  • המטען הייעודי שמכיל את הודעת השגיאה וכתובת אימייל ליצירת קשר עם התמיכה.
  • קוד מצב ה-HTTP שהוחזר בתגובה.
  • ביטוי הסיבה, שהוא תיאור קצר של השגיאה.

יצירת DefaultFaultRule

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

לדוגמה, ההגדרה של TargetEndpoint שמופיעה בהמשך מגדירה ערך DefaultFaultRule שמפעיל מדיניות בשם ReturnJOINError:

<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> לתג <Step> PreFlow, שגרם למדיניות 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 כ 'failure', אלא רק 5xx, או לבקש להחזיר הודעות שגיאה מותאמות אישית עבור קודי תגובת HTTP 400 ו-500.

בדוגמה הבאה, צריך להשתמש במאפיין success.codes כדי להגדיר את TargetEndpoint כך שיטפל בקודי תגובה 400 ו-500 של HTTP כהצלחה, יחד עם קודי ה-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>

עכשיו אפשר להגדיר רכיבי 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
כשלים בניתוב NoRoutesMatched כשל בבחירת TargetEndpoint בעל שם לבקשה
כשלים בסיווג NotFound כשלים שנגרמו על ידי URI של בקשה שלא תואם לאף BasePath עבור אף הגדרה של ProxyEndpoint (כלומר, אין שרתי proxy של API שתואמים לכתובת ה-URL בבקשה של אפליקציית הלקוח)
תחבורה שגיאות ברמת התעבורה של HTTP
קישוריות ConnectionRefused, ConnectionReset, ConnectionTimeout כשלים מתרחשים בעת יצירת חיבורי רשת או ברמת התעבורה
אימותים של בקשות ContentLengthmissing, HostHeadermissing פגמים מתרחשים במהלך בדיקות הסמנטיקה של כל בקשה
אימותים של תשובות מתרחשות שגיאות במהלך בדיקת הסמנטיקה בכל תגובה
שגיאות IO SSLHandshakeError, ReadTimeout, ReadError, WriteTimeout, WriteError, ChunkError שגיאות קריאה/כתיבה בלקוח או ביעד של נקודות קצה, שגיאות זמן קצוב לתפוגה, שגיאות TLS/SSL ושגיאות מקטעים
מערכת שגיאות לא מוגדרות בזמן ריצה
זיכרון OutOfMemory, GCOverLimit כשלים שקשורים לזיכרון
Thread RogueTaskTerminated כשלים כמו סיום של משימות 'ברוח בריחה'.
מדיניות שגיאות בכל סוג מדיניות מוגדרות בחומר העזר בנושא מדיניות.

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

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