API 管理策略中的错误处理

适用于:所有 API 管理层级

通过提供 ProxyError 对象,Azure API 管理允许发布者响应在处理请求期间可能发生的错误条件。 可以通过 ProxyError 属性访问 对象。 on-error策略部分中的策略可以使用对象ProxyError。 本文提供的参考针对 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 发布者可以配置自定义行为,例如记录错误以Azure 事件中心或创建新响应以返回到调用方。

注释

默认情况下,该 on-error 部分不在策略中。 要将 on-error 节添加到策略,请在策略编辑器中浏览到所需策略,然后将其添加进去。 有关配置策略的详细信息,请参阅 API 管理中的策略

on-error如果没有分区,则调用方在出现错误条件时收到 400 或 500 个 HTTP 响应消息。

出错时允许的策略

以下策略可以用在 on-error 策略节中。

LastError

发生错误并控制跳转到 on-error 策略部分时,错误将存储在 上下文中。LastError 属性。 节 on-error 中的策略可以访问 context.LastErrorLastError 具有以下属性。

名称 类型 DESCRIPTION 必选
Source 字符串 发生错误的元素的名称。 可以是策略或内置管道步骤名称。 是的
Reason 字符串 计算机友好错误代码,可以用在错误处理中。
Message 字符串 用户可读的错误说明。 是的
Scope 字符串 出现错误的范围的名称。
Section 字符串 出错的部分名称。 可能的值: inboundbackendoutboundon-error
Path 字符串 指定嵌套策略层次结构,例如 choose[3]\\when[2]。 嵌套策略的多个实例从 1 开始索引。
PolicyId 字符串 在其中发生错误的策略的 id 属性(如果已由客户指定)的值

小窍门

可以通过context.Response.StatusCode访问状态代码。

注释

所有策略都有一个可选的 id 属性,该属性可以添加到策略的根元素。 如果发生错误条件时策略中存在此属性,则可以使用 context.LastError.PolicyId 该属性检索属性的值。

针对内置步骤的预定义错误

针对评估内置处理步骤期间可能发生的错误情况,预定义了以下错误。

来源 条件 原因 消息
配置 URI 与任何 API 或操作不匹配 OperationNotFound 无法匹配操作的传入请求。
授权 未提供订阅密钥 订阅密钥未找到 由于缺少订阅密钥,访问被拒绝。 请确保在向此 API 发出请求时包括订阅密钥。
授权 订阅密钥值无效 订阅密钥无效 由于订阅密钥无效,访问被拒绝。 请确保提供活动订阅的有效密钥。
多个 在请求挂起时,客户端中止了下游连接(从客户端到 API 管理网关的连接) 客户端连接失败 多个
多个 后端中止或无法建立上游连接(从 API 管理网关到后端服务) 后端连接失败 多个
多个 在计算特定表达式期间发生运行时异常 ExpressionValueEvaluationFailure 多个

针对策略的预定义错误

针对策略评估期间可能发生的错误情况,预定义了以下错误。

来源 条件 原因 消息
rate-limit 已超出速率上限 RateLimitExceeded 超出速率限制
配额 超出配额 QuotaExceeded 呼叫量配额已用完 配额会在 xx:xx:xx 复原。 -或- 超出带宽配额。 配额会在 xx:xx:xx 复原。
jsonp 回调参数值无效(包含错误字符) CallbackParameterInvalid 回调参数 {callback-parameter-name} 的值不是有效的 JavaScript 标识符。
IP过滤器 无法分析请求中的调用方 IP FailedToParseCallerIP 无法确定调用方的 IP 地址。 访问被拒绝。
IP过滤器 调用方 IP 不在允许列表中 CallerIpNotAllowed 不允许调用方 IP 地址 {ip-address}。 访问被拒绝。
IP过滤器 调用方 IP 位于阻止列表中 呼叫者IP被封锁 已阻止调用方 IP 地址。 访问被拒绝。
check-header 必需的标头不存在或缺少值 HeaderNotFound 在请求中找不到标头 {header-name}。 访问被拒绝。
check-header 必需的标头不存在或缺少值 HeaderValueNotAllowed 不允许标头 {header-name} 的值 {header-value}。 访问被拒绝。
validate-jwt 请求中缺少 JSON Web 令牌 (JWT) TokenNotPresent JWT 不存在。
validate-jwt 签名验证失败 TokenSignatureInvalid <来自 jwt 库的消息>。 访问被拒绝。
validate-jwt 受众无效 TokenAudienceNotAllowed <来自 jwt 库的消息>。 访问被拒绝。
validate-jwt 颁发者无效 TokenIssuerNotAllowed <来自 jwt 库的消息>。 访问被拒绝。
validate-jwt 令牌已过期 令牌已过期 <来自 jwt 库的消息>。 访问被拒绝。
validate-jwt 无法通过 ID 解析签名密钥 令牌签名密钥未找到 <来自 jwt 库的消息>。 访问被拒绝。
validate-jwt 令牌中缺少必需的声明 TokenClaimNotFound JWT 缺少以下声明: <c1>、 <c2>、 ... 访问被拒绝。
validate-jwt 声明值不匹配 TokenClaimValueNotAllowed 不允许声明 {claim-name} 的值 {claim-value}。 访问被拒绝。
validate-jwt 其他验证失败 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>

发送未经授权的请求会导致以下响应:

屏幕截图显示了对示例的响应,其中包括一条错误消息。

若要详细了解如何使用策略,请参阅: