500 內部伺服器錯誤 - 空白路徑

您目前查看的是 Apigee Edge 說明文件。
前往 Apigee X 說明文件。
info

問題

用戶端應用程式會收到 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"
      }
   }
}

可能原因

如果後端伺服器的要求網址 (以流程變數 target.url 表示) 含有空白路徑,就會發生這個錯誤。

根據規格 RFC 3986 第 3 節:語法元件和 RFC 3986 第 3.3 節:路徑:

  1. URI 語法 包含下列元件:

            foo://example.com:8042/over/there?name=ferret#nose
            \_/   \______________/\_________/ \_________/ \__/
             |            |            |            |       |
          scheme      authority       path        query   fragment
    
  2. path 元件為必要元件,且一律必須包含正斜線 (/),即使路徑中沒有其他字元也一樣。

因此,如果後端伺服器的要求網址完全沒有 path 元件,也就是連正斜線 (/) 都沒有,Apigee Edge 會傳回 500 Internal Server Error 和錯誤碼 protocol.http.EmptyPath。

舉例來說,如果 target.url 的值為 https://www.mocktarget.apigee.net,就會發生這個錯誤,因為 path 元件為空白或遺失。

原因 說明 適用於以下裝置的疑難排解說明
後端伺服器網址 (target.url) 的路徑為空白 流程變數 target.url 代表的後端伺服器網址路徑為空白。 Edge 公有和私有雲使用者

常見的診斷步驟

請使用下列其中一種工具/技術診斷這項錯誤:

API Monitoring

程序 1:使用 API Monitoring

如要使用 API 監控功能診斷錯誤,請按照下列步驟操作:

  1. 以具備 適當角色的使用者身分 登入 Apigee Edge UI。
  2. 切換至要調查問題的機構。

  3. 依序前往「Analyze」>「API Monitoring」>「Investigate」頁面。
  4. 選取您觀察到錯誤的特定時間範圍。
  5. 繪製「錯誤代碼」與「時間」的關係圖。

  6. 選取含有故障代碼 protocol.http.EmptyPath 的儲存格,如下所示:

  7. 故障代碼 protocol.http.EmptyPath 的相關資訊會顯示如下:

  8. 按一下「查看記錄」 ,展開失敗要求所在的資料列。

  9. 在「記錄」視窗中,記下下列詳細資料:
    • 狀態碼: 500
    • 錯誤來源: target
    • 故障代碼: protocol.http.EmptyPath
  10. 如果「Fault Source」(錯誤來源) 為 target,且「Fault Code」(錯誤代碼) 為 protocol.http.EmptyPath,表示後端伺服器網址的路徑為空白。

追蹤記錄

程序 #2:使用追蹤工具

如要使用「追蹤」工具診斷錯誤,請按照下列步驟操作:

  1. 啟用「追蹤工作階段」,並選擇下列其中一種做法:
    • 等待發生 500 Internal Server Error 錯誤,或
    • 如果可以重現問題,請發出 API 呼叫來重現問題 500 Internal Server Error
  2. 確認已啟用「顯示所有流程資訊」:

  3. 選取其中一個失敗的要求,然後檢查追蹤記錄。
  4. 瀏覽追蹤記錄的不同階段,找出發生失敗的位置。
  5. 錯誤通常會出現在「Target Request Flow Started」(目標要求流程已啟動) 階段之後的流程中,如下所示:

  6. 請記下追蹤記錄中的錯誤值。

    error: Request path cannot be empty

    由於 Apigee Edge 是在「Target Request Flow Started」(目標要求流程已啟動) 階段後引發錯誤,因此表示後端伺服器網址中的 path 為空值。如果要求流程中的其中一項政策可能已透過空白路徑更新流程變數 target.url (代表後端伺服器的網址),就最有可能發生這種情況。

  7. 從錯誤點向「Target Request Flow Started」階段回溯,檢查每個流程中的「Variables Read and Assigned」部分。
  8. 找出更新流程變數 target.url 的政策。

    範例追蹤記錄,顯示 JavaScript 政策更新了流程變數 target.url:

    在上述範例追蹤記錄中,請注意流程變數 target.url 的值已在名為「SetTargetURL」SetTargetURL的 JavaScript 政策中更新,如下所示:

    target.url : https://mocktarget.apigee.net
  9. 請注意,target.url 包含下列元件:
    • 配置: https://mocktarget.apigee.net
    • path:空白
  10. 因此您會收到 Request path cannot be empty 錯誤。
  11. 在追蹤記錄中前往「AX」(記錄的 Analytics 資料) AX階段,然後按一下。
  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 ,表示後端伺服器網址的路徑為空白,因此發生這個錯誤。
    回應標頭 值
    X-Apigee-fault-code protocol.http.EmptyPath
    X-Apigee-fault-source target

NGINX

程序 #3:使用 NGINX 存取記錄

如要使用 NGINX 存取記錄診斷錯誤,請按照下列步驟操作:

  1. 如果您是私有雲使用者,可以透過 NGINX 存取記錄判斷 HTTP 500 Internal Server Error 的金鑰資訊。
  2. 檢查 NGINX 存取記錄:

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

  3. 搜尋特定時間內是否有任何錯誤代碼為 500protocol.http.EmptyPath 的錯誤 (如果問題發生在過去),或是否有任何要求仍失敗並顯示 500。
  4. 如果發現任何 500 錯誤,且 X-Apigee-fault-code 與 protocol.http.EmptyPath 的值相符,請判斷 X-Apigee-fault-source 的值。

    NGINX 存取記錄檔中的 500 錯誤範例:

    上述 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 ,表示這個錯誤是由於後端伺服器網址含有空白路徑所致。

原因:後端伺服器網址 (target.url) 的路徑為空白

診斷

  1. 如「常見診斷步驟」一文所述,使用 API 監控、追蹤工具或 NGINX 存取記錄,找出 500 Internal Server Error 的錯誤代碼和錯誤來源。
  2. 如果「Fault Code」為 protocol.http.EmptyPath,且「Fault Source」的值為 target,表示後端伺服器網址有空白路徑。
  3. 後端伺服器網址在 Apigee Edge 中以流程變數 target.url 表示。如果您嘗試更新後端伺服器網址,也就是使用目標要求流程中的任何政策 (在 Proxy/共用流程中),target.url 動態更新後端伺服器網址,使其具有空白路徑,通常就會發生這個錯誤。

  4. 請使用下列其中一個步驟,判斷流程變數 target.url 是否確實有空白路徑,以及其值的來源:

    追蹤記錄

    使用「追蹤」工具

    如果您已擷取這項錯誤的追蹤記錄,請按照「使用追蹤工具 」一文中的步驟操作,並執行下列動作:

    1. 確認 target.url 是否有空白路徑。
    2. 如果是,請找出哪個政策修改或更新 target.url 的值,使其包含空白路徑。

      範例追蹤記錄:顯示 JavaScript 政策更新了流程變數 target.url:

    3. 在上述範例追蹤記錄中,請注意 JavaScript 政策已修改或更新 target.url 的值,使其包含空白路徑。
    4. 請注意,target.url 包含下列元件:
      • 配置: https://mocktarget.apigee.net
      • path: empty

    記錄

    使用記錄伺服器中的記錄

    1. 如果沒有這個錯誤的追蹤記錄 (間歇性問題),請檢查是否已使用 MessageLogging MessageLogging 或 ServiceCallout ServiceCallout 等政策,將流程變數 target.url 的值相關資訊記錄到記錄伺服器。
    2. 如果您有記錄,請查看記錄並:
      1. 確認 target.url 是否有空白路徑,以及
      2. 查看是否能判斷哪個政策修改了 target.url,導致路徑空白

    API Proxy

    查看失敗的 API Proxy

    如果沒有這項錯誤的追蹤記錄或記錄檔,請檢查失敗的 API Proxy,判斷是哪個項目修改或更新流程變數 target.url,導致其中包含無效路徑。請檢查下列事項:

    • API Proxy 中的政策
    • 從 Proxy 叫用的任何共用流程
  5. 請仔細檢查修改或更新流程變數 target.url 的特定政策 (例如 AssignMessage 或 JavaScript),並判斷將 target.url 更新為空白路徑的原因。

    以下列舉幾個政策範例,這些政策會錯誤地更新流程變數 target.url,導致該變數含有空白路徑,進而造成這項錯誤。

    範例 #1

    範例 1:JavaScript 政策更新 target.url 變數

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

    在上述範例中,請注意流程變數 target.url 會以另一個變數 url 中包含的值 https://mocktarget.apigee.net 更新。

    請注意,target.url 包含下列元件:

    • 配置: https://mocktarget.apigee.net
    • path:空白

    由於路徑為空白,Apigee Edge 會傳回 500 Internal Server Error,並顯示錯誤代碼 protocol.http.EmptyPath。

    範例 #2

    範例 2:更新 JavaScript 政策 target.url 變數

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

    在上述範例中,請注意流程變數 target.url 是透過串連變數 url 中包含的值 https://mocktarget.apigee.net 和另一個變數 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 包含下列元件:

    • 配置: https://mocktarget.apigee.netnull
    • path:空白

    範例 #3

    範例 3:透過另一個變數更新 AssignMessage 政策的 target.url 變數

    <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 包含下列元件:

    • 配置: https://mocktarget.apigee.net
    • path:空白

    在上述所有範例中,後端伺服器網址中的路徑 (即 target.url) 為空白,因此 Apigee Edge 會傳回 500 Internal Server Error,並顯示錯誤碼 protocol.http.EmptyPath。

解決方式

根據規格 RFC 3986 第 2 節:語法元件,path 元件為必要元件,且一律須包含正斜線 (/),即使 path 中沒有其他字元也一樣。請按照下列步驟修正這個問題:

  1. 請確保後端伺服器網址 (以流程變數 target.url 表示) 一律具有非空白路徑。
    1. 在某些情況下,路徑中可能沒有資源名稱,請確保路徑至少有一個正斜線 (/)。
    2. 如果您使用任何其他變數來判斷流程變數 target.url 的值,請確保其他變數沒有空白路徑。
    3. 如果您執行任何字串作業來判斷流程變數 target.url 的值,請確保字串作業的結果或輸出內容沒有空白路徑。
  2. 在「診斷」一節討論的範例中,您可以按照下列說明修正這個問題:

    範例 #1

    範例 1:JavaScript 政策更新 target.url 變數

    在變數 url 中加入正斜線 (/),即可修正這個問題,如下所示:

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

    範例 #2

    範例 2:更新 JavaScript 政策 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 變數

    在 AssignMessage 政策的 <Value> 元素中新增有效路徑。舉例來說,您可以將 /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 預期後端伺服器網址 不會有空白路徑,如下列規格所示:

規格
RFC 3986 第 3 節:語法元件
RFC 3986 第 3.3 節:路徑

如果仍需要 Apigee 支援團隊協助,請參閱「必須收集診斷資訊」。

必須收集診斷資訊

如果按照上述指示操作後問題仍未解決,請收集下列診斷資訊,然後與 Apigee Edge 支援團隊聯絡。

如果您是公有雲使用者,請提供下列資訊:

  • 機構名稱
  • 環境名稱
  • API Proxy 名稱
  • 用於重現 500 Internal Server Error 的完整 curl 指令,以及錯誤代碼 protocol.http.EmptyPath
  • API 要求的追蹤記錄檔

如果您是 Private Cloud 使用者,請提供下列資訊:

  • 失敗要求顯示的完整錯誤訊息
  • 環境名稱
  • API Proxy 套裝組合
  • 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

參考資料

流程變數 - 目標