错误码映射插件
用于将后端应答中返回的非正常请求,映射为客户端期望的错误应答的场景。
1. 概述
错误码映射插件用于将后端应答中返回的非正常请求,映射为客户端期望的错误应答的场景。
2. 快速开始
请先参考下面的例子,某后端的返回中,HTTP应答码为200, 但错误信息包含在包体中JSON字段中。
HTTP 200 OK
Content-Type:application/json
{"req_msg_id":"d02afa56394f4588832bed46614e1772","result_code":"ROLE_NOT_EXISTS"}
在这个场景中,客户端期望得到非200的应答,但希望通过不修改后端的方式实现
HTTP 404
X-Ca-Error-Message: Role Not Exists, ResultId=d02afa56394f4588832bed46614e1772
针对描述的中的场景,我们可以按照如下的方式配置错误码映射插件
---
# 参与映射的字段
parameters:
statusCode: "StatusCode"
resultCode: "BodyJsonField:$.result_code"
resultId: "BodyJsonField:$.req_msg_id"
# 映射条件
errorCondition: "$statusCode = 200 and $resultCode <> 'OK'"
# 错误码字段
errorCode: "resultCode"
# 映射项
mappings:
- code: "ROLE_NOT_EXISTS"
statusCode: 404
errorMessage: "Role Not Exists, RequestId=${resultId}"
- code: "INVALID_PARAMETER"
statusCode: 400
errorMessage: "Invalid Parameter, RequestId=${resultId}"
# 默认映射(可选)
defaultMapping:
statusCode: 500
errorMessage: "Unknown Error, ${resultCode}, RequestId=${resultId}"
在这个例子中,我们将后端应答码以及后端应答JSON包体中的result_code
字段设置为了应答条件,如果后端应答码为200,但result_code
字段不等于'OK'
时,开始执行错误码映射,这个例子中,我们使用result_code
作为错误码字段执行映射,配置了两个错误码:当ROLE_NOT_EXISTS
会返回给客户端404应答,而INVALID_PARAMETER
会返回给客户端400应答,其他错误码返回500应答。
3. 插件配置与映射规则
3.1. 插件配置
错误映射插件配置使用json
或yaml
格式配置,各个字段的详细说明如下:
parameters(
必选): 下面配置参与映射的字段,以map
方式配置,参考文档参数与条件表达式的使用errorCondition(
必选): 应答是否属于错误应答的条件表达式,当执行结果为true
时,执行映射errorCode(
可选): 用于指定错误代码
字段,用于匹配mappings
映射列表中的code
字段mappings(
必选): 用于指定映射记录
列表,网关将会用符合错误代码
或错误条件
记录重新构造返回应答,详细字段为code(
可选): 唯一,设置这个字段是codeParameter
字段为必选,当错误代码
与code
字段一致时,执行当前映射记录
condition(
可选): 错误条件表达式,当表达式演算为true
时,执行当前映射记录
statusCode(
必选): 用于指定当前映射记录
的HTTP返回码errorMessage(
可选): 用于指定当前映射记录
的错误信息,体现在应答的X-Ca-Error-Message
头及日志的errorMessage
字段中responseHeaders(
可选): 以Map方式配置,用于设置当前映射记录
的应答头responseBody(
可选): 用于覆写当前映射记录
的应答包体
defaultMapping(
可选): 默认映射记录
,如果mappings
中的所有记录均未命中,则使用本条记录作为应答statusCode(
必选): 用于指定当前映射记录
的HTTP返回码errorMessage(
可选): 用于指定当前映射记录
的错误信息,体现在应答的X-Ca-Error-Message
头及日志的errorMessage
字段中responseHeaders(
可选): 以Map方式配置,用于设置当前映射记录
的应答头responseBody(
可选): 用于覆写当前映射记录
的应答包体
配置规则:
mappingCondition
,mappings[].condition
中的条件表达式使用的参数,与parameters
字段中定义的字段必须对应,否则会报错,关于参数定义与条件表达式,参考参数与条件表达式的使用文档errorCode
字段中使用的参数必须为parameters
中定义的字段mappings
列表记录中的code
与condition
必须配置其中的一个,当配置code
时值必须唯一,当配置condition
时,将按照配置顺序执行,越靠前的优先级越高errorMessage
,responseBody
可以使用类似"${Code}: ${Message}"
的格式对消息进行模板替换,字段取值来自parameters
中提取到的值responseHeaders
的值,也可以使用${Message}
的方式执行模板替换responseBody
不配置时,透传后端应答responseHeaders
不配置时,透传后端应答的Headers, 否则使用配置键值对覆盖后端应答的Header,当值配置为''
时,删除对应的HeaderdefaultMapping
没有配置时,错误码映射不生效,透传后端应答
3.2. 映射参数
映射参数可通过如下的方式在parameters
参数中配置为键值对,其中键作为变量名定义,值可以使用Location:Name
的方式配置,表示从当前应答或系统上下文的特定位置中读取。
---
# 参与映射的字段
parameters:
statusCode: "StatusCode"
resultCode: "BodyJsonField:$.result_code"
resultId: "BodyJsonField:$.req_msg_id"
错误码映射目前支持以下位置的参数,具体参数描述请参考参数与条件表达式的使用文档。
位置名称 | 适用范围 | 说明 |
StatusCode | 应答 | 后端的HTTP应答码,如: |
ErrorCode | 应答 | API网关系统错误码 |
ErrorMessage | 应答 | API网关系统错误消息 |
Header | 应答 | 使用 |
BodyJsonField | 应答* | 使用 |
System | 应答 | 使用 |
Token | 应答 | 当处于 |
ErrorCode
和ErrorMessage
会返回API网关的系统错误码与系统错误信息,请参考错误代码表文档。使用
BodyJsonField
可以使用JSONPath来提取后端返回JSON的值,但如果后端应答的包体大小超过15360 Bytes则这个字段将会无法提取到值,得到的是空值null
3.3. 执行规则
错误码映射插件会按照如下的顺序执行:
根据
parameters
中配置的参数列表,从应答及系统上下文中获取当前的参数表
依据
步骤1
得到的参数表,执行errorCondition
中配置的条件表达式,为true
则继续执行,false
不生效
如果配置了
errorCode
字段,则获取errorCode
字段的值,并寻找与mappings
中code
匹配的映射记录
,
如果步骤3没有匹配到
映射记录
,则依次执行mappings
字段配置了condition
的映射记录
如果步骤3或4中匹配到了
映射记录
,根据对应的配置构造应答,否则构造默认应答
3.4. 系统错误的映射及日志
API网关系统错误码出现在网关的检查、校验、流控、插件处理等场合,参考错误代码表文档,使用
ErrorCode
作为映射参数,可以支持对系统错误码的映射,可用于诸如:客户端仅支持200应答,但希望将被限流的429应答映射为200应答的场景。当出现系统错误时,位置为
StatusCode
,Header
,BodyJsonField
等来自应答的字段取值都将为null
,在写条件表达式时需要注意,未出现系统错误时ErrorCode
位置的取值为OK
。API网关的系统错误码会出现在
X-Ca-Error-Code
应答头及日志的errorCode
字段中,这个值不会被错误码映射插件
改写。日志中的
statusCode
字段记录的是网关递送给客户端的应答码的值,会被错误码映射插件
改写。
4. 配置示例
4.1. 映射包体错误码
映射
---
# 参与映射的字段
parameters:
statusCode: "StatusCode"
resultCode: "BodyJsonField:$.result_code"
resultId: "BodyJsonField:$.req_msg_id"
# 映射条件
errorCondition: "$statusCode = 200 and $resultCode <> 'OK'"
# 错误码字段
errorCode: "resultCode"
# 映射项
mappings:
- code: "ROLE_NOT_EXISTS"
statusCode: 404
errorMessage: "Role Not Exists, RequestId=${resultId}"
- code: "INVALID_PARAMETER"
statusCode: 400
errorMessage: "Invalid Parameter, RequestId=${resultId}"
# 默认映射(可选)
defaultMapping:
statusCode: 500
errorMessage: "Unknown Error, ${resultCode}, RequestId=${resultId}"
4.2 应答body映射
#
# 这个例子用于给前端返回定制的json错误body
---
# 指定映射参数
parameters:
statusCode: "StatusCode"
resultCode: "Header:X-Ca-Error-Code"
requestId: "Header:X-Ca-Request-Id"
errorMessage: "Header:X-Ca-Error-Message"
# 映射条件
errorCondition: "$statusCode != 200"
# 错误码字段
errorCode: "resultCode"
# 映射项
mappings:
- code: "I400MH"
statusCode: 200
responseHeaders:
Content-Type: "application/xml"
X-Ca-Error-Message: ""
X-Ca-Error-Code: ""
responseBody: |
{
"code":"89",
"message":"${errorMessage}",
"resultCode":"${resultCode}"
}
5. 使用限制
参数定义个数不超过16个。
单个表达式的字符数不超过512个字符。
BodyJsonField
位置的字段对应答包体的限制为16380 Bytes, 超过后直接返回空值。插件配置大小限制为50KB。
mappings
中以condition
方式配置映射记录
不超过20条。