500 שגיאת שרת פנימית - EmptyPath

אתם צופים במסמכי התיעוד של Apigee Edge.
כדאי לעיין במסמכי התיעוד של Apigee X.
מידע

תיאור הבעיה

אפליקציית הלקוח מקבלת קוד סטטוס של HTTP‏ 500 Internal Server Error עם קוד השגיאה protocol.http.EmptyPath כתגובה לקריאות ל-API.

הודעת שגיאה

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

HTTP/1.1 500 Internal Server Error

בנוסף, יכול להיות שתופיע הודעת השגיאה הבאה:

{
   "fault":{
      "faultstring":"Request path cannot be empty",
      "detail":{
         "errorcode":"protocol.http.EmptyPath"
      }
   }
}

גורמים אפשריים

השגיאה הזו מתרחשת אם כתובת ה-URL של הבקשה של שרת הבק-אנד, שמיוצגת על ידי משתנה הזרימה target.url, מכילה נתיב ריק.

בהתאם למפרטים RFC 3986, section 3: Syntax Components and RFC 3986, section 3.3: Path:

  1. תחביר ה-URI כולל את הרכיבים הבאים:

            foo://example.com:8042/over/there?name=ferret#nose
            \_/   \______________/\_________/ \_________/ \__/
             |            |            |            |       |
          scheme      authority       path        query   fragment
    
  2. הרכיב path הוא חובה ותמיד צריך לכלול קו נטוי קדימה (/), גם אם אין תווים אחרים כחלק מהנתיב.

לכן, אם כתובת ה-URL של הבקשה בשרת הבק-אנד לא כוללת את הרכיב path, כלומר, היא לא כוללת אפילו לוכסן (/), ‏ Apigee Edge מגיב עם 500 Internal Server Error וקוד השגיאה protocol.http.EmptyPath.

לדוגמה: אם הערך של target.url הוא https://www.mocktarget.apigee.net, השגיאה הזו מתרחשת כי הרכיב path ריק או חסר.

סיבה תיאור הוראות לפתרון בעיות שרלוונטיות ל
לכתובת ה-URL של שרת הקצה העורפי (target.url) אין נתיב לכתובת ה-URL של השרת העורפי שמיוצגת על ידי משתנה הזרימה target.url יש נתיב ריק. משתמשים ב-Edge Public Cloud וב-Edge Private Cloud

שלבים נפוצים לאבחון

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

API Monitoring

תהליך מספר 1: שימוש ב-API Monitoring

כדי לאבחן את השגיאה באמצעות הכלי 'מעקב אחר API':

  1. נכנסים לממשק המשתמש של Apigee Edge בתור משתמש עם תפקיד מתאים.
  2. עוברים לארגון שבו רוצים לבדוק את הבעיה.

  3. עוברים לדף Analyze > API Monitoring > Investigate.
  4. בוחרים את מסגרת הזמן הספציפית שבה נתקלת בשגיאות.
  5. משרטטים את קוד התקלה מול הזמן.

  6. בוחרים תא עם קוד השגיאה protocol.http.EmptyPath כמו בדוגמה הבאה:

  7. המידע על קוד התקלה protocol.http.EmptyPath מוצג כמו בדוגמה הבאה:

  8. לוחצים על הצגת יומנים כדי להרחיב את השורה של הבקשה שנכשלה.

  9. בחלון יומנים, רושמים את הפרטים הבאים:
    • קוד סטטוס: 500
    • מקור התקלה: target
    • קוד תקלה: protocol.http.EmptyPath
  10. אם מקור השגיאה הוא target וקוד השגיאה הוא protocol.http.EmptyPath, המשמעות היא שלכתובת ה-URL של השרת העורפי יש נתיב ריק.

מעקב

תהליך מספר 2: שימוש בכלי המעקב

כדי לאבחן את השגיאה באמצעות הכלי Trace:

  1. מפעילים את trace session ואת אחת מהאפשרויות הבאות:
    • ממתינים להתרחשות השגיאה 500 Internal Server Error, או
    • אם אפשר לשחזר את הבעיה, מבצעים את הקריאה ל-API כדי לשחזר את הבעיה 500 Internal Server Error
  2. מוודאים שהאפשרות הצגת כל פרטי הזרימה מופעלת:

  3. בוחרים אחת מהבקשות שנכשלו ובודקים את המעקב.
  4. עוברים בין השלבים השונים של ה-trace ומאתרים את המקום שבו התרחשה הכשל.
  5. בדרך כלל השגיאה מופיעה בתהליך העבודה אחרי השלב Target Request Flow Started כמו שמוצג בהמשך:

  6. רושמים את ערך השגיאה מהמעקב.

    שגיאה: נתיב הבקשה לא יכול להיות ריק

    השגיאה מופקת על ידי Apigee Edge אחרי השלב Target Request Flow Started, ולכן היא מציינת שהערך של path בכתובת ה-URL של השרת בעורף пустой. התרחיש הזה יקרה כנראה אם משתנה הזרימה target.url (שמייצג את כתובת ה-URL של שרת הקצה העורפי) עודכן עם נתיב ריק דרך אחת ממדיניות הבקשות בתהליך.

  7. בודקים את הקטע Variables Read and Assigned (משתנים שנקראו והוקצו) בכל אחד מהתהליכים, מהנקודה שבה השגיאה התרחשה אחורה לכיוון השלב Target Request Flow Started (תהליך בקשת היעד התחיל).
  8. קובעים את המדיניות שבה מתעדכן משתנה הזרימה target.url .

    דוגמה למעקב שמראה שמדיניות JavaScript עדכנה את משתנה הזרימה target.url:

    בדוגמה שלמעלה, שימו לב שהערך של משתנה הזרימה variable target.url מתעדכן במדיניות JavaScript שנקראת SetTargetURL באופן הבא:

    target.url : https://mocktarget.apigee.net
  9. שימו לב שכתובת ה-URL target.url כוללת את הרכיבים הבאים:
    • scheme: https://mocktarget.apigee.net
    • path: empty
  10. לכן, מוצגת השגיאה Request path cannot be empty.
  11. עוברים לשלב AX (נתוני Analytics שתועדו) בנתוני המעקב ולוחצים עליו.
  12. גוללים למטה לקטע Phase Details - Error Headers וקובעים את הערכים של X-Apigee-fault-code ו-X-Apigee-fault-source כמו שמוצג בהמשך:

  13. הערכים של X-Apigee-fault-code ו-X-Apigee-fault-source יהיו protocol.http.EmptyPath ו-target בהתאמה, מה שמציין שהשגיאה הזו נגרמת כי בכתובת ה-URL של שרת הקצה העורפי יש נתיב ריק.
    כותרות תגובה ערך
    X-Apigee-fault-code protocol.http.EmptyPath
    X-Apigee-fault-source target

NGINX

תהליך מספר 3: שימוש ביומני גישה של NGINX

כדי לאבחן את השגיאה באמצעות יומני הגישה של NGINX:

  1. אם אתם משתמשי Private Cloud, אתם יכולים להשתמש ביומני הגישה של NGINX כדי לקבוע את פרטי המפתח לגבי HTTP 500 Internal Server Error.
  2. בודקים את יומני הגישה של NGINX:

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

  3. מחפשים שגיאות 500 עם קוד שגיאה protocol.http.EmptyPath במהלך פרק זמן מסוים (אם הבעיה התרחשה בעבר) או אם יש בקשות שעדיין נכשלות עם 500.
  4. אם מוצאים שגיאות 500 עם הערך של X-Apigee-fault-code שזהה לערך של protocol.http.EmptyPath, צריך לקבוע את הערך של X-Apigee-fault-source.

    דוגמה לשגיאה 500 מיומן הגישה של NGINX:

    בדוגמה של רשומה מיומן הגישה של NGINX שלמעלה, הערכים של X-Apigee-fault-code ושל X-Apigee-fault-source הם:

    כותרות ערך
    X-Apigee-fault-code protocol.http.EmptyPath
    X-Apigee-fault-source target

    שימו לב שהערכים של X-Apigee-fault-code ו-X-Apigee-fault-source הם protocol.http.EmptyPath ו-target בהתאמה, מה שמצביע על כך שהשגיאה הזו נגרמת בגלל שלכתובת ה-URL של שרת הקצה העורפי יש נתיב ריק.

הסיבה: הנתיב של כתובת ה-URL של שרת הקצה העורפי (target.url) ריק

אבחון

  1. קובעים את קוד השגיאה ואת מקור השגיאה של 500 Internal Server Error באמצעות API Monitoring,‏ Trace Tool או יומני גישה של NGINX, כמו שמוסבר בשלבים נפוצים לאבחון.
  2. אם קוד השגיאה הוא protocol.http.EmptyPath ולמקור השגיאה יש את הערך target, זה מצביע על כך שלכתובת ה-URL של שרת הקצה העורפי יש נתיב ריק.
  3. כתובת ה-URL של שרת הקצה העורפי מיוצגת על ידי משתנה הזרימה target.url ב-Apigee Edge. השגיאה הזו מתרחשת בדרך כלל אם מנסים לעדכן את כתובת ה-URL של שרת הקצה העורפי, כלומר, target.url באופן דינמי באמצעות אחת ממדיניות (בתוך Proxy/shared flow) בתהליך הבקשה של היעד, כך שיהיה לה נתיב ריק.

  4. כדי לבדוק אם משתנה הזרימה target.url אכן מכיל נתיב ריק ואת המקור של הערך שלו, מבצעים את אחד מהשלבים הבאים:

    מעקב

    שימוש בכלי המעקב

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

    1. בודקים אם ב-target.url יש נתיב ריק.
    2. אם כן, צריך לגלות איזו מדיניות שינתה או עדכנה את הערך של target.url כך שיכיל נתיב ריק.

      דוגמה למעקב שמראה שמדיניות JavaScript עדכנה את משתנה הזרימה target.url:

    3. בדוגמה שלמעלה, אפשר לראות שמדיניות JavaScript שינתה או עדכנה את הערך של target.url כך שיכיל נתיב ריק.
    4. שימו לב ש-target.url כולל את הרכיבים הבאים:
      • scheme: https://mocktarget.apigee.net
      • path: empty

    יומנים

    שימוש ביומנים בשרת היומנים

    1. אם אין לכם מעקב אחר השגיאה הזו (בעיה לסירוגין), אתם יכולים לבדוק אם רשמתם ביומן את המידע על הערך של משתנה הזרימה target.url, באמצעות מדיניות כמו MessageLogging או ServiceCallout בשרת היומן שלכם.
    2. אם יש לכם את היומנים, כדאי לעיין בהם ולבדוק:
      1. בודקים אם ל-target.url יש נתיב ריק, ו
      2. בודקים אם אפשר לזהות איזו מדיניות שינתה את target.url כך שיכיל נתיב ריק

    proxy ל-API

    בדיקת ה-proxy ל-API שנכשל

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

    • המדיניות ב-proxy ל-API
    • כל תהליכי העבודה המשותפים שמופעלים מה-proxy
  5. בודקים את המדיניות הספציפית (לדוגמה, AssignMessage או JavaScript) שמשנה או מעדכנת את משתנה רצף הפעולות target.url, ומנסים להבין למה המשתנה target.url עודכן כך שהנתיב שלו ריק.

    הנה כמה דוגמאות לכללי מדיניות שמעדכנים את משתנה הזרימה target.url באופן שגוי כך שיכיל נתיב ריק שמוביל לשגיאה הזו.

    דוגמה 1

    דוגמה 1: משתנה target.url של עדכון מדיניות JavaScript

    var url = "https://mocktarget.apigee.net"
    context.setVariable("target.url", url);

    בדוגמה שלמעלה, אפשר לראות שמשתנה הזרימה target.url מתעדכן עם הערך https://mocktarget.apigee.net שכלול במשתנה אחר url.

    שימו לב ש-target.url כולל את הרכיבים הבאים:

    • scheme: https://mocktarget.apigee.net
    • path: empty

    מכיוון שהנתיב ריק, Apigee Edge מחזיר 500 Internal Server Error עם קוד השגיאה protocol.http.EmptyPath.

    דוגמה מס' 2

    דוגמה מספר 2: משתנה JavaScript Policy updating target.url

    var path = context.getVariable("request.header.Path");
    var url = "https://mocktarget.apigee.net" + path
    context.setVariable("target.url", url);

    בדוגמה שלמעלה, אפשר לראות שהמשתנה של הזרימה target.url מתעדכן על ידי שרשור הערך https://mocktarget.apigee.net שכלול במשתנה url ו הערך של משתנה אחר path, שהערך שלו מאוחזר מ-request.header.Path.

    אם יש לכם גישה לבקשה או למעקב בפועל, תוכלו לאמת את הערך בפועל שהועבר אל request.header.Path.

    בקשה לדוגמה שנשלחה על ידי המשתמש:

    curl -v https://HOST_ALIAS/v1/myproxy -H "Authorization: Bearer <token>
    

    בדוגמה הזו, נתיב הכותרת לא נשלח כחלק מהבקשה. לכן, הערך של נתיב המשתנה במדיניות JavaScript הוא null.

    כך:

    • url = https://mocktarget.apigee.net + path
    • url = https://mocktarget.apigee.net + null
    • target.url = https://mocktarget.apigee.netnull

    שימו לב ש-target.url כולל את הרכיבים הבאים:

    • scheme: https://mocktarget.apigee.netnull
    • path: empty

    דוגמה #3

    דוגמה 3: עדכון של משתנהtarget.url במדיניות AssignMessage באמצעות משתנה אחר

    <AssignMessage async="false" continueOnError="false" enabled="true" name=">AM-SetTargetURL">
        <DisplayName>AM-SetTargetURL</DisplayName>
        <AssignVariable>
             <Name>target.url</Name>
             <Value>https://mocktarget.apigee.net</Value>
        </AssignVariable>
        <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
        <AssignTo createNew="false" transport="http" type="request"/>
    </AssignMessage>

    שימו לב ש-target.url כולל את הרכיבים הבאים:

    • scheme: https://mocktarget.apigee.net
    • path: empty

    בכל הדוגמאות שלמעלה, הנתיב בכתובת ה-URL של שרת הקצה העורפי, כלומר target.url, ריק. לכן, Apigee Edge מחזיר את השגיאה 500 Internal Server Error עם קוד השגיאה protocol.http.EmptyPath.

רזולוציה

בהתאם למפרט RFC 3986, section 2: Syntax Components, the path component is required and it MUST always have a forward slash (/), even if there are no other characters as part of the path. כדי לפתור את הבעיה, מבצעים את השלבים הבאים:

  1. מוודאים שלכתובת ה-URL של השרת העורפי, שמיוצגת על ידי משתנה הזרימה target.url, תמיד יש נתיב לא ריק.
    1. במקרים מסוימים, יכול להיות שלא יהיה שם משאב בנתיב. במקרה כזה, צריך לוודא שבנתיב יש לפחות קו נטוי (/).
    2. אם משתמשים במשתנים אחרים כדי לקבוע את הערך של משתנה הזרימה target.url, צריך לוודא שלמשתנים האחרים אין נתיב ריק.
    3. אם אתם מבצעים פעולות על מחרוזות כדי לקבוע את הערך של משתנה הזרימה target.url, אתם צריכים לוודא שהתוצאה או הפלט של הפעולות על המחרוזות לא כוללים נתיב ריק.
  2. בדוגמאות שמופיעות בקטע אבחון, אפשר לפתור את הבעיה באופן הבא:

    דוגמה 1

    דוגמה 1: משתנה target.url של עדכון מדיניות JavaScript

    כדי לפתור את הבעיה, מוסיפים קו נטוי (/) למשתנה url, כמו בדוגמה הבאה:

    var url = "https://mocktarget.apigee.net/"
    context.setVariable("target.url", url);

    דוגמה מס' 2

    דוגמה מספר 2: משתנה JavaScript Policy updating target.url

    var path = context.getVariable("request.header.Path");
    var url = "https://mocktarget.apigee.net" + path
    context.setVariable("target.url", url);

    כדי לפתור את הבעיה, צריך לוודא שמעבירים נתיב תקין, למשל /iloveapis, כחלק מכותרת הבקשה Path, כמו שמוצג בהמשך:

    בקשה לדוגמה:

    curl -v https://HOST_ALIAS/v1/myproxy -H "Authorization: Bearer <token> -H "Path: /iloveapis"
    

    דוגמה #3

    דוגמה 3: עדכון משתנה של מדיניות AssignMessage target.urlבאמצעות משתנה אחר

    מוסיפים נתיב תקין לרכיב <Value> של מדיניות AssignMessage. לדוגמה, אפשר להגדיר את /json כנתיב עבור MockTarget API. כלומר, משנים את הרכיב <Value> ל-https://mocktarget.apigee.net/json, כמו שמוצג בהמשך:

    <AssignMessage async="false" continueOnError="false" enabled="true" name="AM-SetTargetURL">
        <DisplayName>AM-SetTargetURL</DisplayName>
        <AssignVariable>
             <Name>target.url</Name>
             <Value>https://mocktarget.apigee.net/json</Value>
        </AssignVariable>
        <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
        <AssignTo createNew="false" transport="http" type="request"/>
    </AssignMessage>

מפרט

ב-Apigee Edge מצפים שלכתובת ה-URL של שרת הקצה העורפי לא יהיה נתיב ריק, בהתאם למפרטים הבאים:

מפרט
RFC 3986, section 3: Syntax Components
RFC 3986, section 3.3: Path

אם עדיין דרושה לך עזרה מצוות התמיכה של Apigee, אפשר לעבור אל איסוף מידע לצורך אבחון.

חובה לאסוף נתוני אבחון

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

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

  • שם הארגון
  • שם הסביבה
  • שם ה-proxy ל-API
  • פקודת curl מלאה ששימשה לשחזור 500 Internal Server Error עם קוד השגיאה protocol.http.EmptyPath
  • קובץ מעקב לבקשות ה-API

אם אתם משתמשים ב-Private Cloud, עליכם לספק את הפרטים הבאים:

  • הודעת השגיאה המלאה שזוהתה בבקשות שנכשלו
  • שם הסביבה
  • חבילת proxy ל-API
  • קובץ מעקב לבקשות ה-API
  • יומני גישה של NGINX:

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    הסבר: מחליפים את ORG, ‏ ENV ו-PORT# בערכים האמיתיים.

  • יומני מערכת של מעבד ההודעות /opt/apigee/var/log/edge-message- processor/logs/system.log

קובצי עזר

משתני זרימה – יעד