適用於:所有 API Management 層級
透過提供 ProxyError 物件,Azure API 管理 讓發佈者能回應處理請求時可能發生的錯誤狀況。
ProxyError物件是透過上下文中的LastError屬性存取。 政策區塊中的 on-error 政策可以使用該 ProxyError 物件。 本文提供 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 發佈者可以設定自訂行為,例如將錯誤記錄給 Azure 事件中樞,或建立新的回應回傳給呼叫者。
注意
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 政策區段時,錯誤會被儲存在 上下文中。LastError 屬性。 該區塊中的 on-error 政策可以存取 context.LastError。
LastError 具有以下性質。
| 名稱 | 類型 | 描述 | 必要 |
|---|---|---|---|
Source |
字串 | 錯誤發生的元素名稱。 可能是原則或內建的管線步驟名稱。 | 是的 |
Reason |
字串 | 方便電腦理解的錯誤碼,可用於處理錯誤。 | 否 |
Message |
字串 | 人類可以看懂的錯誤描述。 | 是的 |
Scope |
字串 | 發生錯誤的範圍名稱。 | 否 |
Section |
字串 | 發生錯誤的區段名稱。 可能的值:inbound、、backendoutbound、或on-error。 |
否 |
Path |
字串 | 指定巢狀政策階層,例如 choose[3]\\when[2]。 嵌套策略的多個實例會從 1 開始索引編號。 |
否 |
PolicyId |
字串 | 發生錯誤的原則中,若客戶有指定,則為 id 屬性的值。 |
否 |
提示
你可以透過 context.Response.StatusCode取得狀態碼。
注意
所有原則都有可以新增至原則根元素的選擇性 id 屬性。 如果該屬性在錯誤狀況發生時存在於政策中,你可以利用該 context.LastError.PolicyId 屬性取得該屬性的值。
內建步驟的預先定義錯誤
針對在內建處理步驟評估期間可能會發生的錯誤狀況,系統預先定義了下列錯誤。
| 來源 | 狀況 | 原因 | 訊息 |
|---|---|---|---|
| 組態 | URI 不符合任何 API 或操作 | OperationNotFound | 無法將傳入的請求匹配到操作。 |
| 授權 | 未提供訂用帳戶金鑰 | 找不到訂閱密鑰 | 拒絕存取,因為找不到訂用帳戶金鑰。 在對這個 API 提出要求時,請務必包含訂用帳戶金鑰。 |
| 授權 | 訂用帳戶金鑰值無效 | 訂閱金鑰無效 | 拒絕存取,因為訂用帳戶金鑰無效。 請確保提供適用於作用中訂用帳戶的有效金鑰。 |
| 多個 | 客戶端在請求待處理時中止了從客戶端到API管理閘道器的下游連線 | 客戶連線失敗 | 多個 |
| 多個 | 後端中止或無法建立上游連線(從 API 管理閘道到後端服務) | 後端連接失敗 | 多個 |
| 多個 | 執行時異常發生在特定表達式的評估期間 | 表達式值評估失敗 | 多個 |
原則的預先定義錯誤
針對在原則評估期間可能會發生的錯誤狀況,系統預先定義了下列錯誤。
| 來源 | 狀況 | 原因 | 訊息 |
|---|---|---|---|
| 速率限制 | 超過了速率限制 | 超過速率限制 | 超過速率限制 |
| 配額 | 超過配額 | 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 | 所需標頭未呈現或值遺失 | 標頭值不允許 | 標頭 {header-name} 的值 {header-value} 不被允許。 拒絕存取。 |
| 驗證 JWT | 請求中缺少 JSON Web Token (JWT) | TokenNotPresent | JWT 不存在。 |
| 驗證 JWT | 簽章驗證失敗 | 憑證簽名無效 | 來自 jwt 程式庫的訊息<>。 拒絕存取。 |
| 驗證 JWT | 無效的受眾 | TokenAudienceNotAllowed | 來自 jwt 程式庫的訊息<>。 拒絕存取。 |
| 驗證 JWT | 無效的簽發者 | 不允許的代幣發行者 | 來自 jwt 程式庫的訊息<>。 拒絕存取。 |
| 驗證 JWT | 權杖過期 | 令牌已過期 | 來自 jwt 程式庫的訊息<>。 拒絕存取。 |
| 驗證 JWT | 無法透過 ID 解析簽名金鑰 | 找不到令牌簽名密鑰 | 來自 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>
發送未經授權的請求會得到以下回應:
相關內容
如需使用原則的詳細資訊,請參閱: