错误处理
错误返回接口定义
错误返回包含 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 错误

请求到 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 会自动清理已创建但没有实际内容的助手消息
- 错误定位:通过将错误关联到具体的用户消息,可以精确定位问题所在
错误处理流程
- 用户发送消息时,SDK 创建用户消息对象并添加到消息列表
- 在流式模式下,SDK 预创建一个空的助手消息对象
- 如果请求失败,错误信息会被添加到用户消息对象的
error字段 - 如果助手消息对象为空且出现错误,该空消息会被自动移除
- 用户可以通过检查消息对象的
error字段来展示具体的错误信息
SDK 的错误处理机制分为两个层面:
- 全局错误:
useStream/useAgent返回的全局错误对象,用于展示系统级错误 - 消息级错误: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 场景下的错误处理
工具执行失败
当工具执行失败时,对应的 ToolCallPart 的 status 会变为 '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秒超时
});
超时后,对应 ToolCallPart 的 status 会变为 '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 || '未知错误';
};
@ssv-lab