適用於:所有 APIM 層
藉由提供 ProxyError
物件,Azure API 管理可讓發佈者回應在處理 Proxy 要求期間可能會發生的錯誤狀況。
ProxyError
物件是透過 context.LastError 屬性來存取,並可供 on-error
原則區段中的原則使用。 本文提供 Azure API 管理中錯誤處理功能的參考。
API 管理中的錯誤處理
Azure API 管理中的原則分為 inbound
、backend
、outbound
和 on-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
原則區段。
- 選擇
- 設定變數
- 尋找並替換
- return-response
- set-header
- 設定方法
- set-status
- send-request
- 發送單向請求
- log-to-eventhub
- json-to-xml
- xml-to-json
- limit-concurrency
- 模擬回應
- 重試
- 跟蹤
LastError (最後錯誤)
當發生錯誤且控制項跳至 on-error
原則區段時,該錯誤就會儲存在 context.LastError 屬性中,此屬性可供 on-error
區段中的原則存取。 LastError 具有下列屬性。
名稱 | 類型 | 描述 | 必要 |
---|---|---|---|
Source |
字符串 | 發生錯誤之元素的名稱。 可能是原則或內建的管線步驟名稱。 | 是的 |
Reason |
字符串 | 方便電腦理解的錯誤碼,可用於處理錯誤。 | 否 |
Message |
字符串 | 人類可以看懂的錯誤描述。 | 是的 |
Scope |
字符串 | 發生錯誤的範圍名稱。 | 否 |
Section |
字符串 | 發生錯誤的區段名稱。 可能的值:「輸入」、「後端」、「輸出」或 「錯誤」。 | 否 |
Path |
字符串 | 指定巢狀原則階層,例如“choose[3]\when[2]”。 巢狀原則的多個實例會從 1 編製索引。 | 否 |
PolicyId |
字符串 | 發生錯誤之原則上 id 屬性的值 (如果客戶有指定) |
否 |
提示
您可以透過 context.Response.StatusCode 存取狀態碼。
注意
所有原則都有可以新增至原則根元素的選擇性 id
屬性。 如果在錯誤狀況發生時,原則中有這個屬性,此屬性的值就能使用 context.LastError.PolicyId
屬性來加以擷取。
內建步驟的預先定義錯誤
針對在內建處理步驟評估期間可能會發生的錯誤狀況,系統預先定義了下列錯誤。
來源 | 狀況 | 原因 | 訊息 |
---|---|---|---|
組態 | Uri 不符合任何 API 或作業 | OperationNotFound | 連入要求與作業無法匹配。 |
授權 | 未提供訂用帳戶金鑰 | 找不到訂閱密鑰 | 拒絕存取,因為找不到訂用帳戶金鑰。 在對這個 API 提出要求時,請務必包含訂用帳戶金鑰。 |
授權 | 訂用帳戶金鑰值無效 | 訂閱金鑰無效 | 拒絕存取,因為訂用帳戶金鑰無效。 請務必提供適用於作用中訂用帳戶的有效金鑰。 |
多個 | 要求擱置時,用戶端會中止下游連線 (從用戶端至 API 管理閘道) | 客戶連線失敗 | 多個 |
多個 | 上游連線 (從 API 管理閘道到後端服務) 未建立或由後端中止 | 後端連接失敗 | 多個 |
多個 | 特定運算式評估期間發生執行階段例外狀況 | ExpressionValueEvaluationFailure | 多個 |
原則的預先定義錯誤
針對在原則評估期間可能會發生的錯誤狀況,系統預先定義了下列錯誤。
來源 | 狀況 | 原因 | 訊息 |
---|---|---|---|
速率限制 | 超過了速率限制 | 超過速率限制 | 超過速率限制 |
配額 | 超過配額 | QuotaExceeded | 呼叫量配額不足。 會在 xx:xx:xx 中補充配額。 -或- 頻寬配額不足。 會在 xx:xx:xx 中補充配額。 |
jsonp | 回呼參數值無效 (包含錯誤的字元) | 回調參數無效 | 回呼參數 {callback-parameter-name} 的值不是有效的 JavaScript 識別碼。 |
IP過濾器 | 無法從要求中剖析呼叫端 IP | 無法解析來電者的 IP | 無法建立呼叫端的 IP 位址。 拒絕存取。 |
IP過濾器 | 呼叫端 IP 不在允許清單中 | 呼叫者IP不被允許 | 不允許呼叫端 IP 位址 {ip-address}。 拒絕存取。 |
IP過濾器 | 呼叫端 IP 位於封鎖清單中 | 呼叫者的IP已被封鎖 | 呼叫端 IP 位址遭到封鎖。 拒絕存取。 |
check-header | 所需標頭不存在或找不到值 | HeaderNotFound | 在要求中找不到標頭 {header-name}。 拒絕存取。 |
check-header | 所需標頭不存在或找不到值 | HeaderValueNotAllowed | 不允許標頭 {header-name} 值 {header-value}。 拒絕存取。 |
驗證 JWT | 要求中遺漏 JWT | TokenNotPresent | JWT 不存在。 |
驗證 JWT | 簽章驗證失敗 | 憑證簽名無效 | 來自 jwt 程式庫的訊息<>。 拒絕存取。 |
驗證 JWT | 無效的對象 | TokenAudienceNotAllowed | 來自 jwt 程式庫的訊息<>。 拒絕存取。 |
驗證 JWT | 無效的簽發者 | TokenIssuerNotAllowed | 來自 jwt 程式庫的訊息<>。 拒絕存取。 |
驗證 JWT | 權杖過期 | 令牌已過期 | 來自 jwt 程式庫的訊息<>。 拒絕存取。 |
驗證 JWT | 識別碼未解析簽章金鑰 | TokenSignatureKeyNotFound | 來自 jwt 程式庫的訊息<>。 拒絕存取。 |
驗證 JWT | 權杖中沒有必要的宣告 | TokenClaimNotFound | JWT 遺漏下列宣告: <c1>、 <c2>、 ... 拒絕存取。 |
驗證 JWT | 宣告值不相符 | TokenClaimValueNotAllowed | 不允許宣告 {claim-name} 值 {claim-value}。 拒絕存取。 |
驗證 JWT | 其他驗證失敗 | JwtInvalid(JWT無效) | <來自 jwt 程式庫的訊息> |
forward-request 或 send-request | 未在設定的逾時內收到來自後端的 HTTP 回應狀態碼和標頭 | 暫停 | 多個 |
範例
將 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>
傳送未經授權的要求會導致下列回應:
相關內容
如需使用原則的詳細資訊,請參閱:
- 教學課程:轉換及保護 API
- 原則參考,取得原則陳述式及其設定的完整清單
- 原則運算式
- 設定或編輯原則
- 重複使用原則設定
- 原則程式碼片段存放庫 (英文)
- 原則遊樂場存放庫
- Azure API 管理 原則工具組
- 取得 Copilot 協助以建立、說明及疑難排解原則