API 管理策略中的错误处理Error handling in API Management policies
Azure API 管理通过提供 ProxyError
对象,允许发布服务器响应在处理请求的过程中可能发生的错误情况。By providing a ProxyError
object, Azure API Management allows publishers to respond to error conditions, which may occur during processing of requests. ProxyError
对象可通过 context.LastError 属性访问,并可由 on-error
策略节中的策略使用。The ProxyError
object is accessed through the context.LastError property and can be used by policies in the on-error
policy section. 本文提供的参考针对 Azure API 管理中的错误处理功能。This article provides a reference for the error handling capabilities in Azure API Management.
API 管理中的错误处理Error handling in API Management
Azure API 管理中的策略分为 inbound
、backend
、outbound
和 on-error
部分,如以下示例所示。Policies in Azure API Management are divided into inbound
, backend
, outbound
, and on-error
sections as shown in the following example.
<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>
在处理请求期间,内置的步骤与请求范围内的策略一起执行。During the processing of a request, built-in steps are executed along with any policies, which are in scope for the request. 如果发生错误,处理会立即跳转到 on-error
策略节。If an error occurs, processing immediately jumps to the on-error
policy section.
on-error
策略节可以在任何范围内使用。The on-error
policy section can be used at any scope. API 发布者可配置自定义行为,例如将错误记录到事件中心,或者创建新的需要返回到调用方的响应。API publishers can configure custom behavior such as logging the error to event hubs or creating a new response to return to the caller.
备注
默认情况下,on-error
节不存在于策略中。The on-error
section is not present in policies by default. 要将 on-error
节添加到策略,请在策略编辑器中浏览到所需策略,然后将其添加进去。To add the on-error
section to a policy, browse to the desired policy in the policy editor and add it. 有关配置策略的详细信息,请参阅 API 管理中的策略。For more information about configuring policies, see Policies in API Management.
如果没有 on-error
节,则在出现错误情况时,调用方会收到 400 或 500 HTTP 响应消息。If there is no on-error
section, callers will receive 400 or 500 HTTP response messages if an error condition occurs.
出错时允许的策略Policies allowed in on-error
以下策略可以用在 on-error
策略节中。The following policies can be used in the on-error
policy section.
- choosechoose
- set-variableset-variable
- find-and-replacefind-and-replace
- return-responsereturn-response
- set-headerset-header
- set-methodset-method
- set-statusset-status
- send-requestsend-request
- send-one-way-requestsend-one-way-request
- log-to-eventhublog-to-eventhub
- json-to-xmljson-to-xml
- xml-to-jsonxml-to-json
- limit-concurrencylimit-concurrency
- mock-responsemock-response
- retryretry
- 跟踪trace
LastErrorLastError
当发生错误且控制跳转到 on-error
策略节时,错误会存储在 context.LastError 属性中,该属性可以通过 on-error
节中的策略进行访问。When an error occurs and control jumps to the on-error
policy section, the error is stored in context.LastError property, which can be accessed by policies in the on-error
section. LastError 具有以下属性。LastError has the following properties.
名称Name | 类型Type | 说明Description | 必须Required |
---|---|---|---|
Source |
stringstring | 指定在其中发生错误的元素。Names the element where the error occurred. 可以是策略或内置管道步骤名称。Could be either policy or a built-in pipeline step name. | 是Yes |
Reason |
stringstring | 计算机友好错误代码,可以用在错误处理中。Machine-friendly error code, which could be used in error handling. | 否No |
Message |
stringstring | 用户可读的错误说明。Human-readable error description. | 是Yes |
Scope |
stringstring | 在其中发生错误的范围的名称,可以是以下值之一:“全局”、“产品”、“API”、“操作”Name of the scope where the error occurred and could be one of "global", "product", "api", or "operation" | 否No |
Section |
stringstring | 发生错误的节名称。Section name where error occurred. 可能的值:“inbound”、“backend”、“outbound”或“on-error”。Possible values: "inbound", "backend", "outbound", or "on-error". | 否No |
Path |
stringstring | 指定嵌套策略,例如“choose[3]/when[2]”。Specifies nested policy, for example "choose[3]/when[2]". | 否No |
PolicyId |
stringstring | 在其中发生错误的策略的 id 属性(如果已由客户指定)的值Value of the id attribute, if specified by the customer, on the policy where error occurred |
否No |
提示
可以通过 context.Response.StatusCode 访问状态代码。You can access the status code through context.Response.StatusCode.
备注
所有策略都有一个可选的 id
属性,该属性可以添加到策略的根元素。All policies have an optional id
attribute that can be added to the root element of the policy. 如果出现错误情况时该属性存在于策略中,则可使用 context.LastError.PolicyId
属性检索该属性的值。If this attribute is present in a policy when an error condition occurs, the value of the attribute can be retrieved using the context.LastError.PolicyId
property.
针对内置步骤的预定义错误Predefined errors for built-in steps
针对评估内置处理步骤期间可能发生的错误情况,预定义了以下错误。The following errors are predefined for error conditions that can occur during the evaluation of built-in processing steps.
SourceSource | 条件Condition | ReasonReason | MessageMessage |
---|---|---|---|
配置configuration | URI 与任何 API 或操作均不匹配Uri doesn't match to any API or Operation | OperationNotFoundOperationNotFound | 无法匹配操作的传入请求。Unable to match incoming request to an operation. |
authorizationauthorization | 未提供订阅密钥Subscription key not supplied | SubscriptionKeyNotFoundSubscriptionKeyNotFound | 由于缺少订阅密钥,访问被拒绝。Access denied due to missing subscription key. 请确保在向此 API 发出请求时包括订阅密钥。Make sure to include subscription key when making requests to this API. |
authorizationauthorization | 订阅密钥值无效Subscription key value is invalid | SubscriptionKeyInvalidSubscriptionKeyInvalid | 由于订阅密钥无效,访问被拒绝。Access denied due to invalid subscription key. 请确保提供活动订阅的有效密钥。Make sure to provide a valid key for an active subscription. |
多个multiple | 请求挂起时,客户端中止了下游连接(从客户端到 API 管理网关)Downstream connection (from a client to an API Management gateway) was aborted by the client while request was pending | ClientConnectionFailureClientConnectionFailure | 多个multiple |
多个multiple | 上游连接(从 API 管理网关到后端服务)未建立或已被后端中止Upstream connection (from an API Management gateway to a backend service) was not established or was aborted by the backend | BackendConnectionFailureBackendConnectionFailure | 多个multiple |
多个multiple | 在计算特定表达式期间发生运行时异常Runtime exception had occurred during evaluation of a particular expression | ExpressionValueEvaluationFailureExpressionValueEvaluationFailure | 多个multiple |
针对策略的预定义错误Predefined errors for policies
针对策略评估期间可能发生的错误情况,预定义了以下错误。The following errors are predefined for error conditions that can occur during policy evaluation.
SourceSource | 条件Condition | ReasonReason | MessageMessage |
---|---|---|---|
rate-limitrate-limit | 超出速率限制Rate limit exceeded | RateLimitExceededRateLimitExceeded | 超出速率限制Rate limit is exceeded |
quotaquota | 超出配额Quota exceeded | QuotaExceededQuotaExceeded | 超出调用卷配额。Out of call volume quota. 配额会在 xx:xx:xx 复原。Quota will be replenished in xx:xx:xx. -或- 超出带宽配额。-or- Out of bandwidth quota. 配额会在 xx:xx:xx 复原。Quota will be replenished in xx:xx:xx. |
jsonpjsonp | 回调参数值无效(包含错误字符)Callback parameter value is invalid (contains wrong characters) | CallbackParameterInvalidCallbackParameterInvalid | 回调参数 {callback-parameter-name} 的值不是有效的 JavaScript 标识符。Value of callback parameter {callback-parameter-name} is not a valid JavaScript identifier. |
ip-filterip-filter | 无法分析请求中的调用方 IPFailed to parse caller IP from request | FailedToParseCallerIPFailedToParseCallerIP | 无法确定调用方的 IP 地址。Failed to establish IP address for the caller. 访问被拒绝。Access denied. |
ip-filterip-filter | 调用方 IP 不在允许列表中Caller IP is not in allowed list | CallerIpNotAllowedCallerIpNotAllowed | 不允许调用方 IP 地址 {ip-address}。Caller IP address {ip-address} is not allowed. 访问被拒绝。Access denied. |
ip-filterip-filter | 调用方 IP 位于阻止列表中Caller IP is in blocked list | CallerIpBlockedCallerIpBlocked | 已阻止调用方 IP 地址。Caller IP address is blocked. 访问被拒绝。Access denied. |
check-headercheck-header | 必需的标头不存在或缺少值Required header not presented or value is missing | HeaderNotFoundHeaderNotFound | 在请求中找不到标头 {header-name}。Header {header-name} was not found in the request. 访问被拒绝。Access denied. |
check-headercheck-header | 必需的标头不存在或缺少值Required header not presented or value is missing | HeaderValueNotAllowedHeaderValueNotAllowed | 不允许标头 {header-name} 的值 {header-value}。Header {header-name} value of {header-value} is not allowed. 访问被拒绝。Access denied. |
validate-jwtvalidate-jwt | 请求中缺少 Jwt 令牌Jwt token is missing in request | TokenNotFoundTokenNotFound | 在请求中找不到 JWT。JWT not found in the request. 访问被拒绝。Access denied. |
validate-jwtvalidate-jwt | 签名验证失败Signature validation failed | TokenSignatureInvalidTokenSignatureInvalid | <jwt 库中的消息>。<message from jwt library>. 访问被拒绝。Access denied. |
validate-jwtvalidate-jwt | 受众无效Invalid audience | TokenAudienceNotAllowedTokenAudienceNotAllowed | <jwt 库中的消息>。<message from jwt library>. 访问被拒绝。Access denied. |
validate-jwtvalidate-jwt | 颁发者无效Invalid issuer | TokenIssuerNotAllowedTokenIssuerNotAllowed | <jwt 库中的消息>。<message from jwt library>. 访问被拒绝。Access denied. |
validate-jwtvalidate-jwt | 令牌已到期Token expired | TokenExpiredTokenExpired | <jwt 库中的消息>。<message from jwt library>. 访问被拒绝。Access denied. |
validate-jwtvalidate-jwt | 按 ID 无法解析签名密钥Signature key was not resolved by ID | TokenSignatureKeyNotFoundTokenSignatureKeyNotFound | <jwt 库中的消息>。<message from jwt library>. 访问被拒绝。Access denied. |
validate-jwtvalidate-jwt | 令牌中缺少必需的声明Required claims are missing from token | TokenClaimNotFoundTokenClaimNotFound | JWT 令牌缺少以下声明: <c1>、<c2>、…JWT token is missing the following claims: <c1>, <c2>, … 访问被拒绝。Access denied. |
validate-jwtvalidate-jwt | 声明值不匹配Claim values mismatch | TokenClaimValueNotAllowedTokenClaimValueNotAllowed | 不允许声明 {claim-name} 的值 {claim-value}。Claim {claim-name} value of {claim-value} is not allowed. 访问被拒绝。Access denied. |
validate-jwtvalidate-jwt | 其他验证失败Other validation failures | JwtInvalidJwtInvalid | <jwt 库中的消息><message from jwt library> |
forward-request 或 send-requestforward-request or send-request | 在配置的超时时间内,未从后端收到 HTTP 响应状态代码和标头HTTP response status code and headers were not received from the backend within the configured timeout | 超时Timeout | 多个multiple |
示例Example
将 API 策略设置为以下内容:Setting an API policy to:
<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>
并发送未经授权的请求将导致以下响应:and sending an unauthorized request will result in the following response:
后续步骤Next steps
有关如何使用策略的详细信息,请参阅:For more information working with policies, see:
- API 管理中的策略Policies in API Management
- 转换 APITransform APIs
- 策略参考,获取策略语句及其设置的完整列表Policy Reference for a full list of policy statements and their settings
- 策略示例Policy samples