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 管理中的策略分为 inboundbackendoutboundon-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.

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: