API 统一错误码判定引擎(专业版)
输入
is_retryable(http_status,method="GET");build_error(http_status,biz_code=None,message=None,trace_id="",detail=None)
输出
可重试bool;统一错误体dict{success,code,http,message,trace_id,detail}
硬性规则
- 可重试集合 {408,429,500,502,503,504};POST仅429/503可重试。
- HTTP码经 HTTP_TO_BIZ 映射业务码,自定义biz_code优先。
- 未知码→BIZ_UNKNOWN,不抛异常。
示例
is_retryable(503,"GET") → True;is_retryable(500,"POST") → False
build_error(404,trace_id="t1")["code"] → "BIZ_NOT_FOUND"
build_error(418)["code"] → "BIZ_UNKNOWN"
Python 引擎(可独立运行)
# -*- coding: utf-8 -*-
RETRYABLE_STATUS = {408, 429, 500, 502, 503, 504}
HTTP_TO_BIZ = {
400: ("BIZ_PARAM_ERROR", "参数错误"),
401: ("BIZ_UNAUTHORIZED", "未认证"),
403: ("BIZ_FORBIDDEN", "无权限"),
404: ("BIZ_NOT_FOUND", "资源不存在"),
409: ("BIZ_CONFLICT", "状态冲突"),
422: ("BIZ_VALIDATION", "业务校验失败"),
429: ("BIZ_RATE_LIMITED", "触发限流"),
500: ("SYS_INTERNAL", "系统内部错误"),
502: ("SYS_BAD_GATEWAY", "网关错误"),
503: ("SYS_UNAVAILABLE", "服务不可用"),
504: ("SYS_TIMEOUT", "网关超时"),
}
def is_retryable(http_status, method="GET"):
"""判定是否可安全自动重试。408/429/5xx可重试;
非幂等POST默认不重试,仅429/503例外(限流与暂不可用可安全重发)。"""
if http_status not in RETRYABLE_STATUS:
return False
if method.upper() == "POST" and http_status not in (429, 503):
return False
return True
def build_error(http_status, biz_code=None, message=None, trace_id="", detail=None):
"""生成统一错误响应体;未知HTTP码回落BIZ_UNKNOWN,不抛异常。"""
biz, default = HTTP_TO_BIZ.get(http_status, ("BIZ_UNKNOWN", "未知错误"))
return {"success": False, "code": biz_code or biz, "http": http_status,
"message": message or default, "trace_id": trace_id, "detail": detail}