错误
每个失败的 Bird API 请求都会返回相同的 JSON 错误响应,嵌套在顶层 error 键下。以下是一个空请求体发送请求的真实响应:
代码示例
{
"error": {
"type": "validation_error",
"code": "E01001",
"name": "ValidationError",
"message": "Request has 1 validation error.",
"doc_url": "https://bird.com/docs/api/errors/E01001",
"request_id": "req_01ky7q3hckecgv6d7jpq865532",
"details": [{ "param": "body", "message": "missing properties 'from', 'to'" }]
}
}HTTP 状态由 type 决定。客户端错误使用 400 表示格式错误的请求,401 或 403 表示访问失败,402 表示计费问题,404 表示资源不存在。冲突使用 409,未满足的前置条件使用 412,验证和业务规则失败使用 422,请求速率限制使用 429。Bird 端故障使用 5xx。状态码标识类别;错误响应说明发生了什么。
错误响应字段
| 字段 | 作用 |
|---|---|
| type | 粗粒度分支的宽泛类别:validation_error、auth_error、permission_error、not_found_error、conflict_error、rate_limit_error、billing_error、internal_error,以及少量其他值。这是一个很少扩展的封闭枚举。 |
| code | 不透明的稳定标识符(E01001)。权威引用:唯一,不会重命名,不会复用。当某个错误被弃用时,其 code 会被永久保留。 |
| name | 人类可读的短标识(ValidationError),用于提高日志可读性。始终与 code 配对使用,不可替代它。 |
| message | 人类可读的描述信息。不稳定:措辞可能随时变更。可以展示和记录,但不要解析它。 |
| param | 对于输入相关的错误,标识出问题的字段。不适用时省略。 |
| doc_url | 指向该错误码文档页面的稳定链接。 |
| request_id | 始终存在,同时作为 X-Request-Id 响应请求头返回。在提交支持请求时请引用它;它帮助 Bird 追踪到确切的请求。 |
| details | 字段级验证问题。仅在 validation_error 响应中出现。 |
| remediation | 人类可读的下一步操作,用于解决该错误。在已知恢复方案时出现。 |
| next | 按尝试顺序列出的解决该错误的操作。在具有明确恢复路径的错误中出现,例如未满足的前置条件。 |
| vendor_code | 来自下游系统的原始错误码(SMTP 响应码、支付拒绝码)。仅当 Bird 转发了你可能需要处理的外部系统错误码时出现。 |
使用 type 进行粗粒度处理,使用 code 进行精确处理,不要依赖 message。 典型的客户端基于 type 进行分支(遇到 rate_limit_error 则重试,将 validation_error 展示给用户,遇到 internal_error 则通知相关人员),仅对少数需要特殊处理的错误匹配具体的 code 值。
验证失败:一个错误码,多条详情
字段级验证不会为每个字段和失败的组合分配单独的错误码。所有验证失败都是 E01001 ValidationError,附带一个 details 数组,将每个字段级问题列为 {param, message},就像捕获到的发送失败列出其缺少的属性一样。details 中的 message 字符串可能会变更,仅应用于展示。使用 param 将问题映射到表单字段。
恢复指引:补救措施和下一步
已知修复方法的错误会将其携带在错误响应中。以下是一个真实响应,来自使用缺少所需权限范围的 API 密钥发起的 webhooks 调用:
代码示例
{
"error": {
"type": "permission_error",
"code": "E02035",
"name": "InsufficientScope",
"message": "This request requires the \"webhooks:read\" scope, which your credential has not been granted.",
"param": "webhooks:read",
"doc_url": "https://bird.com/docs/api/errors/E02035",
"request_id": "req_01ky7q4665emc9tw1pxkptaqwq",
"remediation": "Re-authenticate with a credential that has been granted the required scope, then retry."
}
}remediation 是供人类或代理日志使用的一句话;next 在存在时,按尝试顺序列出解决错误的 API 操作(先验证域名,再重试发送)。代理和 CLI 可以直接执行 next;交互式客户端可以直接展示 remediation。
妥善处理错误
- 默认只重试 429 和 5xx,其他不重试。 遇到请求速率限制时遵守 Retry-After(参见请求速率限制),遇到 5xx 使用指数退避,并发送 Idempotency-Key 以确保变更请求的重试是安全的。
- 将 code、name 和 request_id 一起记录日志。 错误码是你在文档和自己日志中搜索的依据;请求 ID 是技术支持所需的信息。
- 容忍新增的错误码和类型。 随着产品发展,新的错误码会定期发布,type 枚举也偶尔会新增值。编写处理程序时使用合理的默认分支,而非穷举匹配。