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. 全局错误useStream / useAgent 返回的全局错误对象,用于展示系统级错误
  2. 消息级错误:Agent 场景下,当某条用户消息发送失败时,错误挂载到对应的用户消息对象上

全局错误展示

typescript
const { parts, error } = useStream({ /* ... */ });

return (
  <div>
    {error && (
      <div className="error-banner">
        <h2>系统错误: {error.message}</h2>
        {error.statusCode && <p>错误码: {error.statusCode}</p>}
      </div>
    )}
    <div>
      {parts.map((part, index) => {
        if (part.type === 'text') return <p key={index}>{part.text}</p>;
        if (part.type === 'reasoning') return <div key={index}>{part.reason}</div>;
        return null;
      })}
    </div>
  </div>
);

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

当用户消息发送失败时,错误信息挂载在对应的用户消息上:

typescript
const { messages } = useAgent({ /* ... */ });

return (
  <div>
    {messages.map((msg) => (
      <div key={msg.id} 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)}>重试</button>
          </div>
        )}
      </div>
    ))}
  </div>
);

Agent 场景下的错误处理

工具执行失败

当工具执行失败时,对应的 ToolCallPartstatus 会变为 'error'error 字段包含错误信息:

typescript
interface ToolCallPart {
  type: 'tool_call';
  id: string;
  name: string;
  status: 'inProgress' | 'complete' | 'error';
  result?: any;
  error?: string;  // status 为 'error' 时包含错误信息
}

在 UI 渲染时处理工具错误状态:

jsx
{message.parts?.map((part, index) => {
  if (part.type !== 'tool_call') return null;

  return (
    <div key={index} className={`tool-call status-${part.status}`}>
      <div>工具: {part.name}</div>
      {part.status === 'inProgress' && <div>执行中...</div>}
      {part.status === 'complete' && (
        <div>执行完成 {part.result && <pre>{JSON.stringify(part.result, null, 2)}</pre>}</div>
      )}
      {part.status === 'error' && (
        <div className="tool-error">工具执行失败: {part.error}</div>
      )}
    </div>
  );
})}

工具超时处理

通过 AGUIPlugin 的 toolTimeout 配置工具执行超时:

js
import { AGUIPlugin } from '@tencent/ssv-ai-sdk-plugin-agui';

new AGUIPlugin({
  toolTimeout: 10000, // 10秒超时
});

超时后,对应 ToolCallPartstatus 会变为 'error'

最佳实践

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. 提供重试机制

typescript
const retryMessage = async (failedMessage: Message) => {
  const newMessages = messages.filter((msg) => msg.id !== failedMessage.id);
  setMessages(newMessages);
  await send({
    input: failedMessage.content,
    files: failedMessage.files || [],
  });
};

3. 错误信息本地化

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

Released under the MIT License.