API 管理原則中的錯誤處理

適用於:所有 API 管理 層

藉由提供 ProxyError 物件,Azure API 管理可讓發佈者回應在處理 Proxy 要求期間可能會發生的錯誤狀況。 ProxyError 物件是透過 context.LastError 屬性來存取,並可供 on-error 原則區段中的原則使用。 本文提供 Azure API 管理中錯誤處理功能的參考。

API 管理中的錯誤處理

Azure API 管理中的原則分為 inboundbackendoutboundon-error 區段,如下列範例所示。

<policies>
    <inbound>
        <!-- statements to be applied to the request go here -->
    </inbound>
    <backend>
        <!-- statements to be applied before the request is
             forwarded to the backend service go here -->
    </backend>
    <outbound>
        <!-- statements to be applied to the response go here -->
    </outbound>
    <on-error>
        <!-- statements to be applied if there is an error
             condition go here -->
    </on-error>
</policies>

在處理要求期間,會執行內建步驟,以及屬於要求範圍內的任何原則。 如果發生錯誤,處理作業會立即跳到 on-error 原則區段。 on-error 原則區段可用在任何範圍。 API 發佈者可以設定自訂行為,例如將錯誤記錄到事件中樞,或建立要傳回給呼叫者的新回應。

注意

依預設,原則中不會有 on-error 區段。 若要在原則中新增 on-error 區段,請在原則編輯器中瀏覽至所要的原則,然後予以新增。 如需如何設定原則的詳細資訊,請參閱 API 管理中的原則

如果沒有 on-error 區段,在發生錯誤狀況時,呼叫端將會收到 400 或 500 HTTP 回應訊息。

on-error 中允許的原則

下列原則可用於 on-error 原則區段。

LastError

當發生錯誤且控制項跳至 on-error 原則區段時,該錯誤就會儲存在 context.LastError 屬性中,此屬性可供 on-error 區段中的原則存取。 LastError 具有下列屬性。

名稱 類型​​ 描述 必要
Source string 發生錯誤之元素的名稱。 可能是原則或內建的管線步驟名稱。 Yes
Reason string 方便電腦理解的錯誤碼,可用於處理錯誤。 No
Message string 人類可以看懂的錯誤描述。 Yes
Scope string 發生錯誤之範圍的名稱,此名稱可為「全域」、「產品」、「API」或「作業」其中之一 No
Section string 發生錯誤的區段名稱。 可能的值:「輸入」、「後端」、「輸出」或 「錯誤」。 No
Path string 指定巢狀原則,例如 "choose[3]/when[2]"。 No
PolicyId string 發生錯誤之原則上 id 屬性的值 (如果客戶有指定) No

提示

您可以透過 context.Response.StatusCode 存取狀態碼。

注意

所有原則都有可以新增至原則根元素的選擇性 id 屬性。 如果在錯誤狀況發生時,原則中有這個屬性,此屬性的值就能使用 context.LastError.PolicyId 屬性來加以擷取。

內建步驟的預先定義錯誤

針對在內建處理步驟評估期間可能會發生的錯誤狀況,系統預先定義了下列錯誤。

來源 Condition 原因 訊息
組態 Uri 不符合任何 API 或作業 OperationNotFound 連入要求與作業無法匹配。
授權 未提供訂用帳戶金鑰 SubscriptionKeyNotFound 拒絕存取,因為找不到訂用帳戶金鑰。 在對這個 API 提出要求時,請務必包含訂用帳戶金鑰。
授權 訂用帳戶金鑰值無效 SubscriptionKeyInvalid 拒絕存取,因為訂用帳戶金鑰無效。 請務必提供適用於作用中訂用帳戶的有效金鑰。
多個 要求擱置時,用戶端會中止下游連線 (從用戶端至 API 管理閘道) ClientConnectionFailure 多個
多個 上游連線 (從 API 管理閘道到後端服務) 未建立或由後端中止 BackendConnectionFailure 多個
多個 特定運算式評估期間發生執行階段例外狀況 ExpressionValueEvaluationFailure 多個

原則的預先定義錯誤

針對在原則評估期間可能會發生的錯誤狀況,系統預先定義了下列錯誤。

來源 Condition 原因 訊息
rate-limit 超過了速率限制 RateLimitExceeded 超過速率限制
quota 超過配額 QuotaExceeded 呼叫量配額不足。 會在 xx:xx:xx 中補充配額。 -或- 頻寬配額不足。 會在 xx:xx:xx 中補充配額。
jsonp 回呼參數值無效 (包含錯誤的字元) CallbackParameterInvalid 回呼參數 {callback-parameter-name} 的值不是有效的 JavaScript 識別碼。
ip-filter 無法從要求中剖析呼叫端 IP FailedToParseCallerIP 無法建立呼叫端的 IP 位址。 拒絕存取。
ip-filter 呼叫端 IP 不在允許清單中 CallerIpNotAllowed 不允許呼叫端 IP 位址 {ip-address}。 拒絕存取。
ip-filter 呼叫端 IP 位於封鎖清單中 CallerIpBlocked 呼叫端 IP 位址遭到封鎖。 拒絕存取。
check-header 所需標頭不存在或找不到值 HeaderNotFound 在要求中找不到標頭 {header-name}。 拒絕存取。
check-header 所需標頭不存在或找不到值 HeaderValueNotAllowed 不允許標頭 {header-name} 值 {header-value}。 拒絕存取。
validate-jwt 要求中沒有 Jwt 權杖 TokenNotPresent JWT 不存在。
validate-jwt 簽章驗證失敗 TokenSignatureInvalid 來自 jwt 程式庫的訊息<>。 拒絕存取。
validate-jwt 無效的對象 TokenAudienceNotAllowed 來自 jwt 程式庫的訊息<>。 拒絕存取。
validate-jwt 無效的簽發者 TokenIssuerNotAllowed 來自 jwt 程式庫的訊息<>。 拒絕存取。
validate-jwt 權杖過期 TokenExpired 來自 jwt 程式庫的訊息<>。 拒絕存取。
validate-jwt 識別碼未解析簽章金鑰 TokenSignatureKeyNotFound 來自 jwt 程式庫的訊息<>。 拒絕存取。
validate-jwt 權杖中沒有必要的宣告 TokenClaimNotFound 下列宣告中沒有 JWT 權杖︰<c1>、<c2>、… 拒絕存取。
validate-jwt 宣告值不相符 TokenClaimValueNotAllowed 不允許宣告 {claim-name} 值 {claim-value}。 拒絕存取。
validate-jwt 其他驗證失敗 JwtInvalid <來自 jwt 程式庫的訊息>
forward-request 或 send-request 未在設定的逾時內收到來自後端的 HTTP 回應狀態碼和標頭 Timeout 多個

範例

將 API 原則設定為:

<policies>
    <inbound>
        <base />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <set-header name="ErrorSource" exists-action="override">
            <value>@(context.LastError.Source)</value>
        </set-header>
        <set-header name="ErrorReason" exists-action="override">
            <value>@(context.LastError.Reason)</value>
        </set-header>
        <set-header name="ErrorMessage" exists-action="override">
            <value>@(context.LastError.Message)</value>
        </set-header>
        <set-header name="ErrorScope" exists-action="override">
            <value>@(context.LastError.Scope)</value>
        </set-header>
        <set-header name="ErrorSection" exists-action="override">
            <value>@(context.LastError.Section)</value>
        </set-header>
        <set-header name="ErrorPath" exists-action="override">
            <value>@(context.LastError.Path)</value>
        </set-header>
        <set-header name="ErrorPolicyId" exists-action="override">
            <value>@(context.LastError.PolicyId)</value>
        </set-header>
        <set-header name="ErrorStatusCode" exists-action="override">
            <value>@(context.Response.StatusCode.ToString())</value>
        </set-header>
        <base />
    </on-error>
</policies>

傳送未經授權的要求會導致下列回應:

未經授權的錯誤回應

下一步

如需使用原則的詳細資訊,請參閱︰