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

הדף הזה רלוונטי ל-Apigee ול-Apigee Hybrid.

לעיון במסמכי התיעוד של Apigee Edge

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

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

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

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

סרטונים

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

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

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

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

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

proxy ל-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:

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

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

בדיקה של FaultRules

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

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

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

דוגמה פשוטה לטיפול בשגיאות

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

לא צריך לצרף את המדיניות לזרימת נתונים, אלא רק ליצור אותה, כמו שמתואר במאמר יצירת המדיניות.

הדוגמה הבאה היא של מדיניות AssignMessage ש:

  • הפונקציה מחזירה הודעת JSON.
  • הפונקציה מגדירה קוד סטטוס של HTTP‏ (911, שהוא קוד סטטוס ברור שלא קיים, רק כדי להמחיש את הגמישות שיש לכם). קוד הסטטוס מופיע בכותרת ה-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>
    </Set>
    <Add>
        <Headers>
            <Header name="invalidKey">Invalid API key!</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!
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>: מערכת Apigee מעריכה את התנאי ומבצעת את המדיניות רק אם התנאי מתקיים. אם יש כמה רכיבי FaultRule שהערך שלהם הוא true, ‏ Apigee מפעיל את הראשון שהערך שלו הוא true. (חשוב: סדר ההערכה של FaultRule, מלמעלה למטה או מלמטה למעלה, שונה בין TargetEndpoint לבין ProxyEndpoint, כפי שמתואר בקטע Multiple FaultRules and execution logic). אם לא כוללים תנאי, הערך של FaultRule הוא true באופן אוטומטי. אבל זו לא שיטה מומלצת. לכל רכיב FaultRule צריך להיות תנאי משלו.

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

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

כמה רכיבי FaultRule ולוגיקת ביצוע

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

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

ביצוע של FaultRules

בקצרה, זו הלוגיקה שבה Apigee משתמש כש-proxy ל-API עובר למצב שגיאה. שימו לב שיש הבדל קל בין ההערכה של FaultRules ב-ProxyEndpoint לבין ההערכה ב-TargetEndpoint.

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

  3. אם לא מופעל FaultRule, ‏ Apigee מפעיל את <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), Apigee
     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, Apigee looks at this FaultRule
     first. But let's say this FaultRule is FALSE. A policy did not
     throw a FailedToResolveAPIKey error. Apigee 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 Apigee 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, Apigee looks at this FaultRule
     first. Let's say this FaultRule is FALSE.
     A policy did not throw a FailedToResolveAPIKey error.
     Apigee 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), Apigee
     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 Apigee 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

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

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

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

ההבדל בין FaultRules לבין המדיניות RaiseFault

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

בקצרה:

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

    לדוגמה, אם רוצים להקפיץ הודעת שגיאה (throw) אם קוד הסטטוס של 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 (קוד סטטוס או מטען ייעודי (payload) של הודעה) משמשים אם הנתונים האלה לא מוגדרים על ידי FaultRule או DefaultFaultRule.
  • אם גם מדיניות RaiseFault וגם FaultRule מוסיפות כותרות HTTP מותאמות אישית, שתיהן נכללות בתגובה. שמות כפולים של כותרות יוצרים כותרת עם כמה ערכים.

הנה דוגמה למה שמוגדר על ידי מדיניות RaiseFault ו-FaultRule, ולמה שמוחזר לאפליקציית הלקוח. הדוגמאות נועדו להיות קצרות, ולא להציג שיטות מומלצות.

מה מוגדר על ידי מדיניות RaiseFault ו-FaultRule.

אפליקציית הלקוח מקבלת:

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

<- מדיניות כללי התקלה מגדירה את הערך הזה:

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

<- מדיניות RaiseFault מגדירה את הערך הזה:

Status Code: 468
Payload: {"DOH!":"Try again."}
Header:
  errorNote: woops

יצירת תנאים

התנאים הם המפתח להפעלת FaultRule. יוצרים תנאים של FaultRule באותו אופן שבו יוצרים תנאים אחרים ב-Apigee, למשל תנאים של זרימות מותנות או של RaiseFault.

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

<FaultRule name="invalid_key_rule">
    <Step>
        <Name>invalid-key-message</Name>
        <Condition>oauthV2.Verify-API-Key-1.failed = true</Condition>
    </Step>
    <Condition>fault.name = "FailedToResolveAPIKey"</Condition>
</FaultRule>

משתנים ספציפיים לשגיאות שקשורות למדיניות

המשתנים 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 וכן הלאה. או אם מדיניות מכסת השימוש נכשלה, אפשר להשתמש במשתנה ratelimit.{quota_policy_name}.exceed.count. אפשר להשתמש בכלי לניפוי באגים ובהפניה למדיניות כדי להבין אילו משתנים ונתוני HTTP זמינים.

מידע נוסף

שיטות מומלצות לטיפול בתקלות

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

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

  • ב-FaultRules, אפשר לציין כל סוג של מדיניות. הדפוס הנפוץ ביותר הוא שימוש במדיניות AssignMessage כדי להגדיר פריטים ספציפיים בתגובת השגיאה בהמתנה. אפשר גם להשתמש ב-AssignMessage כדי להגדיר משתנים שמשמשים למטרות אחרות, למשל, למשתנים שמפנים למדיניות רישום ביומן שמופעלת ב-PostClientFlow או ב-FlowHooks. אפשר גם לשקול רישום של הודעה ביומן, למשל באמצעות המדיניות MessageLogging או המדיניות ServiceCallout, אם רוצים לרשום ביומן שגיאות ספציפיות בתנאי תקלות ספציפיים.
  • אל תציינו מדיניות RaiseFault כשלבים בתוך FaultRule. עדיף להשתמש במדיניות AssignMessage כדי להגדיר או לשנות רכיבי הודעה, כולל מטען ייעודי (payload), כותרות או קוד סטטוס.
  • לכל FaultRule, או לכל FaultRule מלבד האחרון שעבר הערכה, צריך לספק outer <Condition> שמצורף כצאצא של הרכיב <FaultRule>. תנאי הביצוע של FaultRule ללא Condition מפורש שצוין, יחושב באופן מרומז כ-true. רכיב <Condition> שמצורף כרכיב צאצא של רכיב <Step> לא משמש כדי לקבוע אם תנאי ההפעלה של FaultRule מקבל את הערך true או false. תנאי השלב מוערכים רק אחרי ש-Apigee מפעיל את FaultRule שמכיל אותם. ב-FaultRule, נפוץ להשתמש בכמה רכיבי Step עם מדיניות AssignMessage (או מדיניות אחרת), כל אחד עם תנאי Step.
  • כדי לטפל בשגיאות בכמה מדיניות מאותו סוג (לדוגמה, כמה מדיניות Quota), יוצרים FaultRule אחד לכל שגיאת מדיניות שסביר שתקבלו, ואז מבחינים בין שגיאות נפרדות באמצעות תנאים שמצורפים לשלבים. לדוגמה, יוצרים FaultRule לטיפול בשגיאה במדיניות Quota, כמו QuotaViolation, ו-FaultRule נפרד ל-InvalidApiKey. (בהפניה לשגיאות מדיניות מפורטות שגיאות מדיניות. כשמגלים שגיאות נוספות שצריך לטפל בהן, אפשר לחזור מאוחר יותר ולהוסיף אותן ל-FaultRule. אפשר לבצע את הפעולה הזו כמה פעמים, אבל צריך לפרוס מחדש את ה-proxy). הגישה הזו מאפשרת לכם לזהות שגיאות מאותו סוג, לא משנה איזו מדיניות יוצרת אותן, וכך קובץ ה-XML של FaultRule יהיה יעיל.

    התנאים הפנימיים של השלב מאפשרים לכם שליטה מפורטת יותר. לדוגמה, אם אתם אוכפים גם מכסה לכל מפתח וגם מכסה גלובלית באמצעות שתי מדיניות בזרימת הבקשות, צריך להגדיר את התנאי החיצוני FaultRule כך שיופעל בשגיאה QuotaViolation (שמוחזרת כשחורגים מהמכסה בכל אחד מהמקרים). לאחר מכן מגדירים תנאים לשלב כדי להעריך את המשתנים הספציפיים exceed.count בשתי מדיניות המכסות. רק השגיאה הרלוונטית נשלחת ללקוח (חריגה ממכסת המפתחים או חריגה ממכסה גלובלית). דוגמה להגדרה כזו:

    <FaultRule name="over_quota">
      <!-- This condition catches a QuotaViolation in *any* Quota policy -->
      <Condition>fault.name = "QuotaViolation"</Condition>
      <Step>
        <Name>AM-developer-over-quota-fault</Name>
        <Condition>ratelimit.developer-quota-policy.exceed.count GreaterThan 0</Condition>
      </Step>
      <Step>
        <Name>AM-global-over-quota-fault</Name>
        <Condition>ratelimit.global-quota-policy.exceed.count GreaterThan 0</Condition>
      </Step>
    </FaultRule>

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

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

    <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>AM-Generic-Key-Fault</Name>
      </Step>
      <Step>
        <Name>AM-API-Key-NotFound</Name>
        <Condition>fault.name = "FailedToResolveAPIKey"</Condition>
      </Step>
      <Step>
        <Name>AM-API-Key-Invalid</Name>
        <Condition>fault.name = "InvalidApiKey"</Condition>
      </Step>
    </FaultRule>
  • מוסיפים FaultRules במקומות שבהם השגיאות יתרחשו (בצד הלקוח <ProxyEndpoint> או בצד היעד <TargetEndpoint>). כוללים FaultRules לכל מדיניות שמופיעה בכל מיקום.
  • כשמשתמשים במדיניות RaiseFault בשילוב עם FaultRules, צריך לתאם את נתוני התגובה שנשלחים בחזרה כשגם מדיניות RaiseFault וגם FaultRule מחזירות נתונים. לדוגמה, אם יש לכם מדיניות RaiseFault שמגדירה את קוד הסטטוס של HTTP, אל תגדירו גם שלב AssignMessage בתוך FaultRule שמאפס את קוד הסטטוס. התרחיש הגרוע ביותר שיכול לקרות הוא שקוד הסטטוס שמוגדר כברירת מחדל יוחזר לאפליקציית הלקוח.
  • רכיב <DefaultFaultRule> משלים את רכיב <FaultRules> כדי לתת לכם יותר שליטה במדיניות שה-proxy מבצע כשהוא מטפל במצב שגיאה. אם מציינים <DefaultFaultRule>, הוא יופעל אם אחד מהתנאים הבאים מתקיים או אם שניהם מתקיימים:

    • לא בוצעו FaultRule אחרים. מקרה מיוחד הוא אם לא הוגדר אלמנט <FaultRules> בכלל.
    • אם הערך של רכיב הצאצא <AlwaysEnforce> של <DefaultFaultRule> הוא true.

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

    משתמשים ב-<DefaultFaultRule> עם <AlwaysEnforce> שמוגדר כ-true, אם יש לכם מדיניות אחת או יותר שאתם רוצים שה-proxy יבצע תמיד, בלי קשר לשאלה אם בוצע FaultRule קודם. תרחיש אפשרי: נניח שרוצים להוסיף כותרת לתגובה בכל המקרים, בין אם בקשת ה-proxy הובילה לשגיאה ובין אם לא, ובין אם השגיאה טופלה בעבר ובין אם לא. לאחר מכן, צריך לצרף מדיניות AssignMessage מתאימה בקטע <PostFlow>/<Response>, וגם לצרף את אותה מדיניות בקטע <DefaultFaultRule> עם הערך true של <AlwaysEnforce>.

תבנית לטיפול מרכזי בתקלות שאפשר לעשות בה שימוש חוזר

במאמר תבנית לטיפול בשגיאות בשרתי proxy של Apigee מתואר דפוס לטיפול מרכזי בשגיאות ללא כפילות קוד.

יצירת FaultRules

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

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

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

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

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

<AssignMessage name="AM-Invalid-Key">
  <Set>
      <Payload contentType="text/plain">That is an error.</Payload>
      <StatusCode>401</StatusCode>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

שימו לב שלא מצוין רכיב <AssignTo>. כלומר, ההודעה תוקצה להודעה הסביבתית, בהתאם למקום שבו המדיניות מצורפת.

עכשיו אפשר להשתמש במדיניות הזו ב-FaultRule. שימו לב לאופן שבו אתם מפנים למדיניות AssignMessage לפי שם ב-FaultRule:

<ProxyEndpoint name="default">
  ...
  <FaultRules>
    <FaultRule name="invalid_key_rule">
      <Step>
        <Name>AM-Invalid-Key</Name>
      </Step>
      <Condition>fault.name = "InvalidApiKey"</Condition>
    </FaultRule>
  </FaultRules>
</ProxyEndpoint>

כשפורסים את ההגדרה שלמעלה, proxy ל-API יפעיל את מדיניות AssignMessage שנקראת AM-Invalid-Key בכל פעם שאפליקציה מציגה מפתח API לא תקין.

אפשר להפעיל כמה כללי מדיניות ב-FaultRule, כמו בדוגמה הבאה:

<ProxyEndpoint name="default">
  ...
  <FaultRules>
    <FaultRule name="invalid_key_rule">
      <Step>
        <Name>AM-Invalid-Key</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> כדי להגדיר את תגובת השגיאה המותאמת אישית שנשלחת בחזרה ללקוח בשגיאה InvalidApiKey (ראו את הדוגמה הקודמת של FaultRules).

<AssignMessage name="AM-Invalid-Key">
  <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>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

התשובה הזו כוללת:

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

יצירת DefaultFaultRule

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

לדוגמה, בהגדרת TargetEndpoint שבהמשך מוגדר DefaultFaultRule שמפעיל מדיניות בשם AM-Return-Generic-Error:

<TargetEndpoint name="default">
  ...
  <FaultRules>
    ...
  </FaultRules>

  <DefaultFaultRule name="fault-rule">
    <Step>
      <Name>AM-Return-Generic-Error</Name>
    </Step>
  </DefaultFaultRule>

  <HTTPTargetConnection>
    <URL>https://mytarget.example.net</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

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

לדוגמה, מגדירים את מדיניות AssignMessage הבאה כדי להחזיר שגיאה כללית:

<AssignMessage name="AM-Return-Generic-Error">
  <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>AM-Return-Generic-Error</Name>
    </Step>
    <AlwaysEnforce>true</AlwaysEnforce>
  </DefaultFaultRule>

אחד מהשימושים ב-DefaultFaultRule הוא לקבוע את סוג השגיאה שמתרחשת כשאין אפשרות לקבוע אותו בדרך אחרת. לדוגמה, אם proxy ל-API נכשל בגלל שגיאה שלא הצלחתם לזהות, אתם יכולים להשתמש ב-DefaultFaultRule כדי להפעיל את מדיניות AssignMessage הבאה. המדיניות הזו כותבת את הערך fault.name בכותרת שנקראת Unhandled-Fault בתגובה:

<AssignMessage name="AM-Set-Fault-Header">
  <Set>
    <Headers>
      <Header name="Unhandled-Fault">{fault.name}</Header>
    </Headers>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

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

הוספת רישום ביומן של הודעות ל-PostClientFlow

PostClientFlow הוא הרצף היחיד שמופעל אחרי שה-proxy עובר למצב שגיאה. אפשר לצרף לזרימה הזו רק את המדיניות MessageLogging, שמופעלת אחרי שהתשובה נשלחת בחזרה ללקוח. למרות שצירוף מדיניות MessageLogging לזרימה הזו הוא לא טיפול בשגיאות, אפשר להשתמש בה כדי לרשום מידע ביומן במקרה של שגיאה. היא מופעלת בלי קשר להצלחה או לכישלון של ה-proxy, ולכן אפשר להציב מדיניות של Message Logging ב-PostClientFlow ולהיות בטוחים שהיא תמיד תופעל.

טיפול בתקלות שקשורות למדיניות בתהליך הנוכחי

בכל הדוגמאות שמוצגות עד עכשיו נעשה שימוש ב-FaultRule ב-ProxyEndpoint או ב-TargetEndpoint כדי לטפל בשגיאות במדיניות כחלק ממצב השגיאה. הסיבה לכך היא שערך ברירת המחדל של רכיב continueOnError במדיניות הוא false, כלומר כשמתרחשת שגיאה במדיניות, השליטה מועברת למצב השגיאה. כשנמצאים במצב השגיאה, אי אפשר להחזיר את השליטה לצינור הרגיל, ובדרך כלל מחזירים הודעת שגיאה כלשהי לאפליקציה שקוראת ל-API.

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

בדוגמה הבאה מוצגת מדיניות VerifyAPIKey בשם verify-api-key עם הרכיב continueOnError שהערך שלו הוא true:

<VerifyAPIKey continueOnError="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 נעשה שימוש בתנאי כדי לבדוק אם קיימת שגיאה. אם התרחשה שגיאה במדיניות VerifyAPIKey, המדיניות שנקראת FaultInFlow מופעלת. אחרת, המדיניות 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-HERE</Name>
  </Step>
  <Condition>fault.name = "RaiseFault"</Condition>
</FaultRule>

שימו לב שהתנאי בודק אם יש תקלה בשם RaiseFault. המדיניות RaiseFault תמיד מגדירה את הערך של fault.name ל-RaiseFault. אפשר גם להגדיר משתנים מותאמים אישית במדיניות RaiseFault. אם תעשו את זה, תוכלו לבדוק את המשתנים האלה ברכיבי התנאי.

טיפול מותאם אישית בקודי שגיאה של HTTP משרת היעד

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

כברירת מחדל, ב-Apigee קודי תגובה של HTTP בטווח 1xx-3xx נחשבים כהצלחה, וקודי תגובה של HTTP בטווח 4xx-5xx נחשבים ככישלון. כלומר, כל תגובה משירות ה-Backend עם קוד תגובת HTTP‏ 4xx-5xx מפעילה באופן אוטומטי את מצב השגיאה, ואז מחזירה הודעת שגיאה ישירות ללקוח ששלח את הבקשה.

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

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

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