macOS 错误码与处理
口径说明
融云公开文档不覆盖 macOS 原生 SDK 与桌面交付链(dmg / 代码签名 / 公证 / 分发 / Gatekeeper);本页为本项目按 Apple 与 Electron 官方实践补齐的接入文档。
桌面端不新增错误码:所有失败都来自 errors.json 的客户端 / SDK 错误码,由主进程返回 RcResult,渲染进程按码值映射 UI 状态。桌面特有的失败(签名、公证、Gatekeeper、打包)不是 IM 错误码,见对应页面。
返回信封
| 层 | 信封 | 说明 |
|---|---|---|
| 主进程 IMLib | RcResult {code,data?,msg?} | 成功 code=0;经 preload 桥透传同一信封 |
| preload / 渲染进程 | RcResult | 不抛异常,按 `code` 分支处理 |
| WebSocket | Frame {id?,type:'error',data:{code,message}} | SDK 转为 RcResult 错误码 |
连接失败的错误码(已与 iOS / errors.json 对齐)
| 场景 | 返回 | 说明 / 处理 |
|---|---|---|
| Token 无效 / 过期 / 签名不对 | 1002 INVALID_TOKEN | 握手阶段服务端回 401 {"code":1002};msg 为服务端原文(如 invalid token)。不会自动重连,提示重新登录 |
| Token 被禁用 / 无权限 | 1003 FORBIDDEN | 服务端原样透传;不会自动重连 |
| 服务端不可达 / 断网 | 3001 SDK_NETWORK | 传输层错误,按退避策略自动重连 |
| 连接超时(未收到 hello) | 3002 SDK_TIMEOUT | 传输层错误,按退避策略自动重连 |
| 旧接法返回 3004 | 3004 SDK_UNSUPPORTED | 历史问题(已修复):把 service 错误拆成 service.client 或传了不完整对象;统一传 initService() 的返回值即可 |
| 连接未就绪时发消息 | 3001 | 等待 CONNECTED 后重试;UI 展示离线状态 |
认证失败不重连,网络失败才重连
认证类失败(1002/1003)会标记为手动关闭,不会按退避策略自动重连;此前拿被拒凭据无限重试会表现为“一直转圈”。
网络类失败(3001/3002)仍自动重连;UI 建议:1002 → 「登录已过期,请重新登录」,3001/3002 → 「网络异常,正在重连」。
实现说明:浏览器 / undici 的 WebSocket 在握手失败时拿不到 HTTP 状态码,SDK 会在失败路径用一次带 Upgrade 头的 HTTP 探测读回状态码与 body,再映射为 1002/1003/3001;正常连接没有额外开销。主进程日志示例:
Text
[im-electron] connect failed: code=1002 msg=invalid token serverUrl=https://im.example.com ws=global全量对照与兼容枚举
桌面端与 iOS 共用同一份运行时码表(43 条);融云 iOS 公开状态码目录另有 440 条兼容枚举,逐行对照见 状态码全量对照(440 条)。
兼容枚举不会出现在桌面端运行时返回中:排障请以本页码表与主进程返回的 code / msg 为准。
客户端 / SDK 错误码
| 错误码 | 名称 | 分类 | 可重试 | 桌面端处理建议 |
|---|---|---|---|---|
1001 | INVALID_PARAMETER | 客户端 | 否 | 参数错误:检查目标会话、内容长度与选项;提示用户修正后重试。 |
1002 | INVALID_TOKEN | 客户端 | 否 | Token 无效:跳转登录,向业务服务重新获取 Token 后重连。 |
1003 | FORBIDDEN | 客户端 | 否 | 无权限:隐藏对应入口并提示无操作权限。 |
1004 | USER_NOT_FOUND | 客户端 | 否 | 用户不存在:提示 ID 错误或用户已注销。 |
1005 | GROUP_NOT_FOUND | 客户端 | 否 | 群组不存在:刷新会话列表并提示群已解散。 |
1006 | NOT_GROUP_MEMBER | 客户端 | 否 | 未加入群组:引导先加入群组。 |
1007 | MESSAGE_TOO_LARGE | 客户端 | 否 | 消息体过大:压缩图片 / 文件或截断文本后重试。 |
1008 | RATE_LIMITED | 客户端 | 是 | 发送过于频繁:展示“发送太快”并退避。 |
1009 | GROUP_MUTED | 客户端 | 否 | 已被禁言:禁用输入区并提示禁言状态。 |
1010 | SENSITIVE_WORD | 客户端 | 否 | 内容含敏感词:提示修改后重发。 |
1011 | BLOCKED | 客户端 | 否 | 拉黑关系:提示无法发送。 |
1012 | CHATROOM_NOT_FOUND | 客户端 | 否 | 聊天室不存在:退出聊天室页面。 |
1013 | CHATROOM_CLOSED | 客户端 | 否 | 聊天室已销毁:返回会话列表。 |
1014 | NOT_CHATROOM_MEMBER | 客户端 | 否 | 未加入聊天室:先加入再发送。 |
1015 | MEMBERSHIP_LIMIT | 客户端 | 否 | 成员数量超限:提示容量已满。 |
1016 | USER_BANNED | 客户端 | 否 | 账号封禁:跳转申诉流程。 |
1017 | APP_DISABLED | 客户端 | 否 | 应用停用:提示联系管理员。 |
1022 | RECALL_EXPIRED | 客户端 | 否 | 超过撤回时限:隐藏撤回入口。 |
1023 | MESSAGE_ALREADY_RECALLED | 客户端 | 否 | 消息已撤回:替换为撤回占位。 |
1025 | QUOTA_EXCEEDED | 客户端 | 是 | 超出配额:提示稍后重试。 |
1026 | MESSAGE_NOT_EXPANDABLE | 客户端 | 否 | 映射为提示 / 失败态,按可重试性决定是否自动重试。 |
1027 | EXPANSION_LIMIT_EXCEEDED | 客户端 | 否 | 映射为提示 / 失败态,按可重试性决定是否自动重试。 |
1028 | REACTION_INVALID | 客户端 | 否 | 映射为提示 / 失败态,按可重试性决定是否自动重试。 |
1029 | REACTION_LIMIT_EXCEEDED | 客户端 | 否 | 映射为提示 / 失败态,按可重试性决定是否自动重试。 |
1030 | REACTION_USER_LIMIT_EXCEEDED | 客户端 | 否 | 映射为提示 / 失败态,按可重试性决定是否自动重试。 |
1031 | TAG_LIMIT_EXCEEDED | 客户端 | 否 | 映射为提示 / 失败态,按可重试性决定是否自动重试。 |
1032 | TAG_NOT_FOUND | 客户端 | 否 | 映射为提示 / 失败态,按可重试性决定是否自动重试。 |
1033 | TAG_CONVERSATION_LIMIT_EXCEEDED | 客户端 | 否 | 映射为提示 / 失败态,按可重试性决定是否自动重试。 |
1034 | CONVERSATION_NOT_FOUND | 客户端 | 否 | 映射为提示 / 失败态,按可重试性决定是否自动重试。 |
1035 | MESSAGE_REJECTED_BY_CALLBACK | 客户端 | 否 | 映射为提示 / 失败态,按可重试性决定是否自动重试。 |
3001 | SDK_NOT_CONNECTED | SDK 本地 | 是 | 长连接未就绪:展示离线状态,CONNECTED 后自动重试。 |
3002 | SDK_TIMEOUT | SDK 本地 | 是 | 请求超时:展示重试按钮。 |
3003 | SDK_NETWORK_ERROR | SDK 本地 | 是 | 网络错误:展示网络异常条,等待自动重连。 |
3004 | SDK_UNSUPPORTED | SDK 本地 | 否 | 当前平台不支持该能力:降级或隐藏入口。 |
主进程 / 渲染进程错误处理示例
JavaScript
// 渲染进程:桥返回 RcResult,按 code 映射 UI;不要吞掉未知码
const res = await window.niPaasIMBridge.imlib.sendTextMessage(1, targetId, text);
if (res.code !== 0) {
if (res.code === 1002 || res.code === 1003) showReLogin(); // 认证失败:不自动重连
else if (res.code === 3001 || res.code === 3002) showReconnectBanner(); // 传输层:SDK 自动重连
else markMessageFailed(res.code, res.msg);
console.warn('[im] send failed', res.code, res.msg);
}不要吞掉未知错误码
遇到未在码表内的 code,保留原值并记录日志(含 code / msg / 场景),便于后续补充;不要把未知错误统一提示为“网络错误”。