Skip to content

Socket.IO chat_error 事件 — 前端适配指南

关联 Issue:TFRS-105 后端版本:自本次修复起可用

背景

当 Robot 执行过程中发生异常(如 embedding 文本超限、工具调用失败等),后端现在会通过 Socket.IO 向前端推送 chat_error 事件。此前这类错误被 Celery 静默吞掉,前端无感知。

事件概览

/chat 命名空间下现有三种业务事件:

事件名 方向 用途 DTO 定义
chat_message Server → Client Robot 回复消息 BaseMessageDto
chat_event Server → Client 工具调用等轨迹事件 BaseEventTransitionDto
chat_error Server → Client Robot 执行错误 ChatErrorDto

三者均通过 Room 广播到对应会话的所有客户端,前端需 join_conversation 后才能收到。

chat_error 数据结构

interface ChatError {
  /** 发生错误的会话 ID */
  conversationId: string;
  /** 用户可见错误描述(取用类错误 = 服务端 user_message;未知 code 时用它兜底展示) */
  error: string;
  /** 错误发生时间戳,毫秒级 */
  createTimestamp: number;
  /** 稳定机器可读标识(仅取用类错误携带,取值见下方词表;运行时错误无该字段) */
  code?: string;
}

后端 DTO 定义:tfrobotserver/dtos/v1/chat/event.py :: ChatErrorDto

字段命名遵循项目统一的 camelCase 序列化约定(HttpModel + alias_generator),与 chat_message、chat_event 一致。

前端监听示例

// 加入会话房间(已有逻辑)
socket.emit('join_conversation', { conversation_id: conversationId });

// 监听 chat_error 事件
socket.on('chat_error', (data: ChatError) => {
  console.error(`[会话 ${data.conversationId}] 错误: ${data.error}`);

  // 建议:在聊天界面展示错误提示
  showErrorNotification({
    conversationId: data.conversationId,
    message: data.error,
    timestamp: data.createTimestamp,
  });
});

常见错误场景

⚠️ 不要按文案前缀匹配。 本文档早期版本建议客户端按 机器人无法初始化* 之类的前缀映射 错误类型。该契约是脆的:服务端改一个字,客户端映射就静默失效。TFRS-365 已为取用类错误引入 稳定 error code(tfrobotserver/exceptions/robot_exceptions.py :: RobotAcquisitionErrorCode), 请以 code 为准。

Robot 取用失败的稳定 code 词表

code 含义 是否会自动重试 用户可见文案(服务端 user_message)
robot.acquisition.config_absent 尚无已发布的线上 ROBOT 配置(合法状态,非故障) 否 机器人尚未完成配置,请联系管理员在配置中心发布配置后重试。
robot.acquisition.build_failed 有配置但本次构建失败,判定为瞬时(DB 抖动 / 发布竞态 / Embedding 短时限流) 是(memory 侧任务级退避 3 次) 机器人暂时不可用,请稍后重试。
robot.acquisition.dependency_permanent 外部依赖需人工干预(额度不足 / 凭证失效 / 欠费) 否(等待无用,需人处理) 机器人依赖的外部服务当前不可用(额度不足或凭证失效),请联系管理员处理后重试。
robot.acquisition.config_invalid 配置内容本身非法(工具重名 / 导入路径非法 / factory 版本不兼容) 否(改配置并重新发布才恢复) 机器人配置存在错误,当前无法启动,请联系管理员检查配置并重新发布。
robot.acquisition.id_mismatch 实例 rid 与任务透传 robot_id 不符(部署 / 路由错) 否 系统内部路由异常,请刷新页面后重试;若持续出现请联系管理员。

每个异常同时有两层文案:user_message(上表,可直接展示给业务用户)与 str(exc)(运维详情, 含 robot_id 等内部标识符,只进日志与运维接口,不要展示给终端用户)。

其它运行时错误

错误消息模式 触发原因 建议的用户提示
文本长度超过向量化模型允许的最大长度 * 会话上下文过长,embedding 超限 "消息过长,请缩短内容或开启新会话"
其他 Robot 运行时异常 "处理消息时出错,请重试"

✅ 当前状态:code 已下发(TFRS-366)

ChatErrorDto 现含 code(可选);robot_run 已重排(先解析消息拿 conversationId,再取用 Robot),取用类失败会先 sio.emit("chat_error", ...) 再原样重抛 —— 正常链路下前端会收到带 code 的事件。例外(降级为服务端告警,见 _emit_chat_error 回落分支):Socket.IO 断连(对端 API 重启窗口)、消息缺 conversationId、事件发送自身失败。运行时错误(robot.run() 内部异常) 无 code 字段(exclude_none 序列化,与 TFRS-366 前 payload 字节级一致),前端按「未知名 code 回退 error 文案」处理——该渲染侧工作属 TFRF-126。

版本边界:code 词表与 API 侧枚举校验同次发布演进。滚动部署窗口(新 worker + 旧 API) 中,新 code 会被旧 API 的 ChatErrorDto 枚举校验拒绝(事件到不了前端,仅回错给 worker 侧); 前端「未知 code 回退」只针对已过 API 校验、前端不认识的 code 值。

与已有 error 事件的区别

维度 error 事件 chat_error 事件
语义 Socket.IO 协议级错误(消息格式错误、认证失败等) 业务级错误(Robot 执行失败)
推送目标 特定客户端 (to=sid) 会话 Room 内所有客户端
数据结构 { status: "error", message: string } ChatErrorDto(含 conversationId、createTimestamp)
触发来源 Socket.IO Namespace 层 Celery Worker → Socket.IO 转发

注意事项

  1. 向后兼容:chat_error 是新增事件。未监听此事件的前端版本不会受影响,只是无法显示错误提示(与修复前行为一致)。
  2. 错误仍会导致任务失败:后端在发送 chat_error 后会重新抛出异常,Celery 任务标记为失败。前端不需要额外处理任务状态。
  3. 消息不会丢失:错误发生时,用户发送的消息已入库,仅 Robot 回复失败。用户可以重新发送或等待问题修复后重试。