百积木文档
开发集成

CModel 错误模型

CModel Error Contract 1.0.0 的三字段响应结构、HTTP 语义和调用规则。

CModel Error Contract 1.0.0 用于百积木拥有的非流式 HTTP 和 Module 调用边界。公共响应只包含 contractVersionerrorCodedata 三个字段;服务不能再输出 valuesystemCurrentTimeerror{ success, message }{ code, message } 等私有响应。

公共机器可读源事实与 SDK:

每个公开 API 必须在自身文档中登记调用方能够观察和处理的稳定 errorCode。平台内部可以保留错误目录、分类、诊断信息和类型,但这些内部字段不能序列化进公共响应,也不能改变 CModel 固定的 HTTP 200

适用边界

本契约适用于百积木拥有的非流式 HTTP API 和 Module 方法响应。

以下边界保留各自的协议 envelope,并由最外层 Adapter 与 CModel 做一次确定性转换:

  • 健康检查和就绪探针;
  • SSE、WebSocket 等已经发出响应头的流式协议;
  • MCP、OpenAI、Anthropic 和第三方供应商协议;
  • 浏览器重定向、文件下载等非 JSON 响应。

外部错误格式不能继续进入百积木内部业务链路。

成功响应

{
  "contractVersion": "1.0.0",
  "errorCode": "0",
  "data": {
    "id": "example"
  }
}

成功响应必须同时满足:

  • HTTP 状态为 200
  • contractVersion 缺省时按 1.0.0 解析;显式提供时必须为严格 SemVer 1.0.0
  • errorCode 为字符串 "0"
  • data 由具体 API 或 Runtime 方法的返回类型定义。

使用 CModel envelope 的接口不能返回 204 No Content

失败响应

{
  "contractVersion": "1.0.0",
  "errorCode": "PAYMENT_REQUIRED",
  "data": {
    "message": "当前账户余额不足,请充值后重试",
    "retryable": false
  }
}

失败响应必须同时满足:

  • HTTP 状态为 200
  • errorCode 是非 "0" 的稳定字符串错误码;
  • data 可以为 null,或包含必填 messageretryable 的标准公开错误详情对象;
  • message 是 1 到 512 个字符、可直接展示给用户的安全文案;retryable 表示在不改变输入、授权或账户状态时,原操作能否通过重试成功。

业务失败必须使用 HTTP 200。HTTP 只表示 CModel envelope 已被正常传输,业务成败只由 errorCode 表达:"0" 为成功,非 "0" 为失败。网关、代理或容器在 CModel Handler 之外产生的非 200 响应属于传输或基础设施失败,不得伪装成 CModel 业务响应。

Envelope 与业务数据边界

CModel envelope 解析器只读取并校验三个已知字段:

  • contractVersion
  • errorCode
  • data

解析器必须忽略其他顶层字段。旧响应中残留的 valuesystemCurrentTimeerror 及其子字段都按未知顶层字段处理,不能导致协议解析失败,也不能继续作为业务判断或用户展示来源。为兼容协议版本字段引入前的 1.0.0 响应,消费者在 contractVersion 缺失时必须补成 1.0.0;一旦字段存在,非法 SemVer 或非 1.0.0 版本仍是协议错误。新生产者只能输出三个标准字段,并显式输出 contractVersion

成功响应 data 的内部结构不由 CModel envelope 校验,具体 API、Module 方法或 Runtime methodDefinition 负责定义和校验。失败响应 data 由 CModel 统一定义为 null 或标准公开错误详情;消费者必须校验 messageretryable,并原样保留对象中的未知属性,以允许具体 API 在 1.0.0 中追加已文档化的公开操作信息。未知属性不能用于错误分类;分类仍只依赖该 API 登记的稳定 errorCode

错误身份与公开边界

平台内部错误目录可以继续保存错误所有者、原因、分类、重试语义、用户文案和诊断索引,但公共调用方只依赖当前 API 文档登记的:

  • errorCode
  • 该 API 对此错误的稳定说明
  • data.message,仅用于用户展示
  • data.retryable,仅用于决定是否自动重试

最外层 Adapter 负责把内部错误确定性映射成 errorCode,只把已经审查为可公开展示的用户文案和稳定重试语义写入失败 data,并把有效 CModel envelope 统一输出为 HTTP 200。原始上游错误消息、数据库错误、堆栈、Token、Secret、内部域名、完整请求体和个人数据不能进入公共响应。

HTTP 消费规则

调用方收到有效 CModel envelope 后,必须解析 envelope 并以 errorCode 判断业务结果:

  1. HTTP 200 可以承载成功或业务失败;errorCode == "0" 为成功,非 "0" 为失败。
  2. 失败响应的 data 可以是 null 或标准 { message, retryable } 对象;null 兼容已有生产者。
  3. contractVersion 缺失时按 1.0.0 处理;显式值非法或不受支持时报告协议错误,不做版本协商。
  4. 不接受数字 0error_code、顶层 code/message 或缺失 errorCode
  5. 忽略所有未知顶层字段;成功 data 交给具体接口的类型解析器,失败 data 交给 CModel 标准错误详情解析器。标准解析器校验 messageretryable 并保留端点扩展字段,但不得用扩展字段猜测错误类别。
  6. 错误分类只使用 errorCode 和当前 API 文档;不得用 HTTP 状态、valuedata.message 或上游自然语言文本分类。

为支持已上线服务滚动迁移,SDK 1.1.4 的消费者可以解析历史非 200 失败 envelope,但仍只依据非零 errorCode 返回业务失败;所有新生产者和已迁移生产者必须输出 HTTP 200。当生产者盘点确认不再存在历史响应后,删除这项有明确退出条件的 consumer 兼容行为。

流式错误

流式协议不使用 CModel envelope。负责该流的协议必须定义自己的版本化错误事件,并在进入百积木非流式业务边界时由所属 Adapter 完成一次确定性转换。

不得把流内失败当作普通文本、成功数据或 JSON 解析异常吞掉。

收敛要求

生产者、消费者和 Gateway 必须直接收敛到同一个 1.0.0 三字段模型:

  1. 消费者只解析三个已知字段并忽略未知顶层字段;缺失的 contractVersion 统一规范化为 1.0.0
  2. 生产者只序列化三个字段。
  3. Gateway 保留已经校验的三字段失败响应和 errorCode,对调用方统一输出 HTTP 200
  4. 不增加双版本或版本协商;滚动迁移兼容只存在于 SDK consumer 边界,并以生产者全量迁移为删除条件。
  5. 生产者/消费者契约测试必须同时覆盖 HTTP 200 成功与失败、未知顶层字段、成功 data 类型所有权,以及失败 datanull 和标准错误详情两种形态。

本页内容