阅读主题
错误码与故障处理
平台失败响应为 {"error":{"code":"INVALID_AUTH_CODE","message":"登录凭证无效、已使用或不属于当前游戏"}}。用 HTTP 状态判断类别,用 error.code 决定操作;不要依赖提示文字保持不变。requestId 在共享类型中可选,当前实现没有保证每个错误都携带它。
登录核心接口
| HTTP | 错误码 | 含义与处理 |
|---|---|---|
| 400 | VALIDATION_ERROR | 字段缺失、格式或长度不符;检查接口契约,多余兑换字段也会被拒绝 |
| 400 | INVALID_JSON | JSON 无法解析;检查请求编码及序列化 |
| 401 | INVALID_GAME_KEY | 服务端密钥缺失、错误、过长或不属于该游戏;仅由游戏服务端排查 |
| 401 | INVALID_AUTH_CODE | 授权码过期、已使用、App ID 或 PKCE 不匹配;重新登录 |
| 401 | UNAUTHENTICATED | Bearer 请求头缺失或格式无效;恢复有效会话或重新登录 |
| 401 | SESSION_EXPIRED | 玩家会话不存在、过期或凭据类型不对;清理本地会话并重新登录 |
| 403 | ACCOUNT_RESTRICTED | 玩家账号受限;停止自动重试并展示客服入口 |
| 403 | APP_UNAVAILABLE | 应用待审、停用或所属开发者受限;检查控制台状态 |
| 403 | ORIGIN_FORBIDDEN | 浏览器来源不在允许列表;核对协议、主机、端口与 CORS 配置 |
| 404 | APP_NOT_FOUND | App ID 不存在;以控制台值为准 |
| 413 | PAYLOAD_TOO_LARGE | JSON 超过 32 KB;只提交接口需要的字段 |
| 429 | RATE_LIMITED | 请求过于频繁;退避,不立即循环重试 |
| 500 | INTERNAL_ERROR | 服务端未预期错误;保留操作时间、路径与脱敏日志进行排查 |
HTTP 状态不唯一对应某一个原因。例如登录兑换中,应用检查在密钥检查之前,错误密钥配上待审 App ID 可能先返回 APP_UNAVAILABLE。应以实际 error.code 为准。
玩家业务补充
以下错误涉及当前实现的登录、订单、钱包和权益;并非都属于本版四路径 OpenAPI。
| 错误码 | 恢复方式 |
|---|---|
INVALID_CREDENTIALS / INVALID_SMS_CODE | 让用户重新输入或完成新的验证,不泄露账号是否存在 |
MAINTENANCE | 维护期停止下单与登录重试,刷新配置后展示提示 |
FEATURE_DISABLED | 当前应用功能已关闭,刷新玩家中心并隐藏相应入口 |
GAME_BACKEND_REQUIRED | 新应用不能用内置演示免密兑换,配置自己的可信游戏服务器 |
IDEMPOTENCY_CONFLICT | 同一请求 ID 被用于不同内容;新业务动作生成新 ID,原请求重试保持原内容 |
INSUFFICIENT_BALANCE | 刷新余额、显示不足并让用户选择下一步 |
ORDER_NOT_FOUND | 订单不存在或不属于当前账号/游戏;检查当前会话,不暴露他人订单 |
ORDER_NOT_PAYABLE / ORDER_NOT_CLOSABLE | 先查询订单状态,按当前状态更新按钮 |
ASSET_CONSUMED / BENEFIT_CONSUMED | 本地退款条件不满足,展示原因及客服路径 |
完整购买与退款排错见 订单指南。
网络错误与状态不确定
浏览器 CORS 拦截、连接失败和超时可能让客户端拿不到平台 JSON,此时不要伪造业务错误码。记录本地故障类别并给出可恢复提示。兑换超时重新发起登录;支付超时先查询原订单,不能直接显示支付失败并重复创建新订单。
联调日志记录时间、方法、路径、App ID、HTTP 状态与业务码即可。不要记录服务端密钥、授权码、verifier、密码、完整 token 或完整手机号。报告问题时可附脱敏请求字段及复现步骤。
启动错误不属于 HTTP 错误
PRODUCTION_NOT_READY 是设置生产模式后启动即抛出的保护错误,不会作为正常运行 API 的业务响应返回。真实支付、短信及游戏服履约接通前,不应通过删除该保护把演示环境暴露为正式服务。后续工作见 生产接入边界。
实现依据
packages/server/src/app.ts:错误处理中间件、请求校验、鉴权与限流。packages/server/src/platform.ts:订单、钱包、权益和幂等错误。packages/contracts/src/index.ts:ApiErrorBody。