Skip to content
On this page

错误处理

错误返回接口定义

错误返回包含 HTTP 错误和 AI 业务错误,HTTP 错误一定会返回 statusCode + message,业务错误会返回 message + data

  • message:具体的错误信息
  • statusCode:HTTP 网络错误的状态码-404/500/502
  • cause:代码错误的原因位置
  • data:与错误相关的任何原始数据
typescript
interface AIErrorOptions {
  message: string; // 具体的错误信息,包括 HTTP 错误信息 + 内部业务错误信息
  statusCode?: number; // 网络错误的状态码 404/500/502
  cause?: unknown; // 错误的原始原因
  data?: unknown; // 错误的原始数据
}

举几个错误的例子。

请求的接口 404 错误

404错误示例

请求到 AI 接口后业务返回错误

业务错误示例

响应拦截器中的业务错误配置

当我们接入 SDK 的时候,需要配置 responseInterceptor,在 responseInterceptor 中我们需要自定义当前业务的错误配置。

例如我们接入了 LKE,当 LKE 内部业务报错的时候,会返回 error 对象,error 对象中包括 message + code,业务错误中一般会返回 code,则我们可以直接使用。如果你接入的 API 的业务错误返回没有 message,需要指定 message = error.msg

typescript
responseInterceptor(res) {
  if (!res) return res;

  try {
    const messageID = res.message_id;

    if (res.type === 'reply') {
      let content = res.payload?.content;
      return {
        ...res.payload,
        messageID,
        isFromSelf: res.payload?.is_from_self,
        content,
      };
    }

    if (res.type === 'error') {
      return {
        messageID,
        error: {
          ...res.error,
          message: res.error.message
        },
      };
    }

    return res;
  } catch (e) {
    console.error("LKE 响应处理错误:", e);
  }

  return res;
}

错误处理机制

SDK 采用了精确的错误处理策略来提供更好的用户体验:

错误归属

  • 用户消息错误:当用户发送消息失败时,错误信息会被挂载到对应的用户消息对象上
  • 空消息清理:如果在流式模式下出现错误,SDK 会自动清理已创建但没有实际内容的助手消息
  • 错误定位:通过将错误关联到具体的用户消息,可以精确定位问题所在

错误处理流程

  1. 用户发送消息时,SDK 会创建用户消息对象并添加到消息列表
  2. 在流式模式下,SDK 会预创建一个空的助手消息对象
  3. 如果请求失败,错误信息会被添加到用户消息对象的 error 字段
  4. 如果助手消息对象为空且出现错误,该空消息会被自动移除
  5. 用户可以通过检查消息对象的 error 字段来展示具体的错误信息

SDK 的错误处理机制分为两个层面:

  1. 全局错误useChat Hook 会返回一个全局错误对象(如果是小程序或者 Vue2,则直接使用 data 中的 error 对象),用于展示系统级错误。

  2. 消息级错误:当某条用户消息发送失败时,错误信息会被挂载到对应的用户消息对象上。这样可以明确知道是哪条消息导致的错误,提供更精准的错误定位。

您可以使用这些错误对象在 UI 中呈现错误,例如显示错误消息、禁用提交按钮或显示重试按钮。

全局错误展示

全局错误主要用于展示系统级别的错误,如网络连接问题、配置错误等:

typescript
const { messages, error } = useChat({
  api: {
    chatEndpoint: 'https://wss.lke.cloud.tencent.com/v1/qbot/chat/sse',
  },
  mode: 'stream',
  streamFormat: 'chunked',
  plugins: [new LKEPlugin({ filterSerialNumber: true })],
});

return (
  <div>
    {/* 全局系统错误提示 */}
    {error && (
      <div className="error-banner">
        <h2>系统错误: {error.message}</h2>
        {error.statusCode && <p>错误码: {error.statusCode}</p>}
      </div>
    )}

    {/* 消息列表 */}
    <div>
      {messages.map((msg) => (
        <div key={msg.id}>
          <div>{msg.content}</div>
        </div>
      ))}
    </div>
  </div>
);

消息级别错误展示(推荐)

当用户消息发送失败时,错误信息会被挂载到对应的用户消息上。这样可以清楚地知道是哪条消息出现了问题,提供更精准的错误提示:

typescript
const { messages } = useChat({
  api: {
    chatEndpoint: 'https://wss.lke.cloud.tencent.com/v1/qbot/chat/sse',
  },
  mode: 'stream',
  streamFormat: 'chunked',
  plugins: [new LKEPlugin({ filterSerialNumber: true })],
});

return (
  <div>
    {messages.map((msg) => (
      <div key={msg.id}>
        <div className={`message ${msg.role}`}>
          <div>{msg.content}</div>

          {/* 用户消息的错误提示 */}
          {msg.role === 'user' && msg.error && (
            <div className="message-error">
              <span>发送失败: {msg.error.message}</span>
              <button onClick={() => retryMessage(msg.id)}>重试</button>
            </div>
          )}
        </div>
      </div>
    ))}
  </div>
);

注意:错误信息会被挂载到用户消息上,而不是助手消息上。当发送失败时,如果之前创建了空的助手消息,SDK 会自动清理这些空消息。

最佳实践

1. 优先使用消息级错误处理

推荐优先使用消息级错误处理,因为它能提供更精准的错误定位:

typescript
// 推荐做法
{
  messages.map((msg) => (
    <div key={msg.id} className={`message ${msg.role}`}>
      <div>{msg.content}</div>
      {msg.role === 'user' && msg.error && (
        <div className="error-tip">
          发送失败: {msg.error.message}
          <button onClick={() => retryMessage(msg)}>重试</button>
        </div>
      )}
    </div>
  ));
}

2. 结合全局错误和消息级错误

在实际应用中,可以同时使用全局错误和消息级错误:

  • 全局错误:用于展示系统级错误(网络问题、配置错误等)
  • 消息级错误:用于展示特定消息的发送失败

3. 提供重试机制

为用户提供重试功能,提升用户体验:

typescript
const retryMessage = (failedMessage: Message) => {
  // 重新设置输入内容和文件
  setInput(failedMessage.content);
  setFiles(failedMessage.files || []);

  // 移除失败的消息
  const newMessages = messages.filter((msg) => msg.id !== failedMessage.id);
  setMessages(newMessages);

  // 重新发送
  chat();
};

4. 错误信息的本地化

根据实际业务需求,可以对错误信息进行本地化处理:

typescript
const getErrorMessage = (error: any) => {
  if (error.statusCode === 404) {
    return '服务暂时不可用,请稍后重试';
  }
  if (error.statusCode === 500) {
    return '服务器内部错误,请联系管理员';
  }
  return error.message || '未知错误';
};

Released under the MIT License.