SPECIFICATION
第 9 章:错误码与一致性级别
本章定义 CAP 协议的标准化错误码表,以及实现声明一致性级别的方式。
9.1 错误码格式
错误码使用 E_ 前缀的大写下划线命名。错误码字符串本身具有规范性——本规范的实现 MUST 按本章定义返回对应的错误码字符串,以便跨实现的一致诊断。
错误响应消息结构:
ErrorBody {
required error_code : string
required message : string
optional details : map<string, string>
optional retry_after_ms : uint32
}
| 字段 | 说明 |
|---|---|
error_code | 本章定义的标准错误码 |
message | 人类可读的错误描述(语言不固定,建议英文或 zh-CN) |
details | 错误的附加上下文(如违反的具体字段) |
retry_after_ms | 客户端重试的建议等待时间,仅对暂时性错误有意义 |
9.2 凭证相关错误码
适用于 Authorization_Descriptor 和 Trusted_Ticket 的校验失败场景。
| 错误码 | HTTP 等价 | 触发条件 | 一致性 |
|---|---|---|---|
E_DESCRIPTOR_NOT_FOUND | 404 | 引用的 descriptor_id 在终端本地未找到 | 终端 MUST |
E_INVALID_STRUCTURE | 400 | 凭证结构不符合 §2.3 / §2.4 | 终端/签发方 MUST |
E_INVALID_SIGNATURE | 401 | 签名校验失败 | 终端 MUST |
E_VERIFICATION_KEY_INVALID | 401 | 签名 key_id 对应的 Verification_Key 未注册或已撤销 | 终端 MUST |
E_UNKNOWN_ISSUER | 401 | 凭证的 issuer_id 不在终端信任列表 | 终端 MUST |
E_DESCRIPTOR_REVOKED | 403 | Authorization_Descriptor 已被撤销 | 终端 MUST |
E_TICKET_REVOKED | 403 | Trusted_Ticket 已被撤销 | 终端 MUST |
E_DESCRIPTOR_EXPIRED | 403 | 凭证已过 not_after | 终端 MUST |
E_DESCRIPTOR_NOT_YET_VALID | 403 | 当前时间早于 not_before | 终端 MUST |
E_TICKET_MALFORMED | 400 | JWS 解析失败或 typ 不正确 | 终端 MUST |
E_DUPLICATE_DESCRIPTOR_ID | 409 | 提交的凭证与已存储凭证 ID 冲突且内容不一致 | 终端 MUST |
E_VALIDITY_OUT_OF_RANGE | 400 | 凭证的 not_after - not_before 超出限制 | 终端/签发方 MUST |
E_REVOCATION_QUERY_TIMEOUT | 504 | 在线撤销查询超时 | 终端 SHOULD |
9.3 授权范围错误码
适用于凭证合法但授权范围不匹配的场景。
| 错误码 | HTTP 等价 | 触发条件 |
|---|---|---|
E_SUBJECT_MISMATCH | 403 | 凭证 subject 与请求方 fay_id 不匹配 |
E_TERMINAL_MISMATCH | 403 | 凭证 terminal_id 与当前终端不匹配 |
E_AUTHORIZATION_INSUFFICIENT | 403 | 找不到匹配 (resource, mode) 的 Grant |
E_RATE_LIMIT_EXCEEDED | 429 | 超过 constraints 中的频率限制 |
E_OUT_OF_TIME_WINDOW | 403 | 当前时间不在 constraints 时间窗口内 |
E_OUT_OF_GEO_FENCE | 403 | 终端位置不在 constraints 地理围栏内 |
E_UNSUPPORTED_CONSTRAINT | 400 | 凭证含有未识别的 constraint 键 |
9.4 资源与会话错误码
适用于资源占用、Session 状态相关的错误。
| 错误码 | HTTP 等价 | 触发条件 |
|---|---|---|
E_RESOURCE_BUSY | 409 | 资源在请求模式下已被占用(违反读写锁矩阵) |
E_RESOURCE_UNAVAILABLE | 503 | 资源当前不可用(硬件断开、软件未运行等) |
E_RESOURCE_NOT_FOUND | 404 | resource_id 不存在 |
E_SESSION_NOT_FOUND | 404 | session_id 不存在 |
E_SESSION_TERMINATED | 410 | Session 已终止,无法继续操作 |
E_SESSION_LIMIT_EXCEEDED | 429 | 超过 §5.8 定义的 Session 数量限制 |
E_OS_INTEGRATION_FAILED | 500 | OS 访问控制下发失败 |
9.5 交接相关错误码
适用于第 6 章定义的交接流程。
| 错误码 | HTTP 等价 | 触发条件 |
|---|---|---|
E_HANDOVER_INVALID_SOURCE | 400 | source_session_id 不存在或状态不允许交接 |
E_HANDOVER_INVALID_TARGET | 400 | target_credential 校验失败 |
E_HANDOVER_REJECTED_BY_POLICY | 403 | 策略评估拒绝交接 |
E_HANDOVER_FAILED_AT_RELEASE | 500 | 交接过程中源 Session 释放失败 |
E_HANDOVER_FAILED_AT_ACQUIRE | 500 | 交接过程中目标 Session 创建失败 |
E_HANDOVER_TIMEOUT | 504 | 交接超时 |
E_HANDOVER_IN_PROGRESS | 409 | 资源已有交接进行中,新请求被拒绝 |
E_HANDOVER_RETRY_LIMIT | 429 | 重试次数超过限制 |
9.6 协议与系统错误码
| 错误码 | HTTP 等价 | 触发条件 |
|---|---|---|
E_PROTOCOL_VERSION_UNSUPPORTED | 400 | 消息 version 字段不被实现支持 |
E_INVALID_MESSAGE | 400 | 协议消息格式不符合 §2.6 |
E_INTERNAL_ERROR | 500 | 终端内部错误(不暴露细节) |
E_NOT_IMPLEMENTED | 501 | 实现未提供该可选能力 |
E_STORAGE_FULL | 507 | 终端凭证存储已满 |
9.7 错误码扩展
实现 MAY 定义自定义错误码,但 MUST:
- 使用
E_VENDOR_<vendor_name>_<code>命名格式(如E_VENDOR_ACME_QUOTA_EXCEEDED) - 不与本章定义的标准错误码冲突
- 在实现文档中明确语义
iFay_Runtime 在收到未识别的自定义错误码时 SHOULD 视为 E_INTERNAL_ERROR 处理。
9.8 一致性级别声明
实现 MUST 通过以下方式声明所满足的一致性级别。
9.8.1 一致性声明结构
ConformanceClaim {
required protocol_version : string // 如 "1.0.0" 或 "draft"
required levels : array<ConformanceLevel> (len 1..3)
optional optional_features : array<string>
optional vendor_extensions : array<string>
}
ConformanceLevel = enum["terminal", "issuer", "runtime"]
| 字段 | 说明 |
|---|---|
protocol_version | 实现遵循的 CAP 协议版本号 |
levels | 实现满足的一致性级别(参见 §0.5) |
optional_features | 实现支持的可选能力(如 aggregated_heartbeat、ai_model_handover_policy) |
vendor_extensions | 实现支持的厂商扩展能力 |
9.8.2 声明发布渠道
实现 SHOULD 通过以下渠道发布 ConformanceClaim:
- 在产品文档中明确声明
- 通过特定查询接口返回(具体接口由实现定义)
- 在 SDK 包元数据中声明
9.8.3 一致性测试
CAP 协议的一致性测试套件(Conformance Test Suite)作为辅助资产由项目维护,但不在本规范的规范性范围内。任何实现 SHOULD 通过对应一致性级别的测试套件,但 MUST 不依赖测试套件作为正确性的唯一保证。
9.9 错误码使用建议
实现 SHOULD 遵循以下错误码使用原则:
- 优先选择最具体的错误码:例如
E_TICKET_REVOKED优于E_TICKET_MALFORMED(即使两者都可能在分析过程中出现) - 不通过错误码暴露内部细节:错误 message 字段中避免暴露密钥指纹、内部 ID 等敏感信息
- details 字段提供诊断辅助:例如
details["field"] = "not_after"表明具体哪个字段不合规 - 暂时性错误使用 retry_after_ms:例如
E_RESOURCE_BUSY、E_HANDOVER_IN_PROGRESS
9.10 错误码与 schema.json 的同步
schema/{version}/schema.json MUST 包含完整的错误码枚举定义,与本章保持一致。当本章错误码列表更新时,schema.json MUST 同步更新。
