错误处理
错误返回接口定义
错误返回包含 HTTP 错误和 AI 业务错误,HTTP 错误一定会返回 statusCode + message,业务错误会返回 message + data
message
:具体的错误信息statusCode
:HTTP 网络错误的状态码-404/500/502cause
:代码错误的原因位置data
:与错误相关的任何原始数据
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
。
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 的错误处理机制分为两个层面:
全局错误:
useChat
Hook 会返回一个全局错误对象(如果是小程序或者 Vue2,则直接使用 data 中的 error 对象),用于展示系统级错误。消息级错误:当某条用户消息发送失败时,错误信息会被挂载到对应的用户消息对象上。这样可以明确知道是哪条消息导致的错误,提供更精准的错误定位。
您可以使用这些错误对象在 UI 中呈现错误,例如显示错误消息、禁用提交按钮或显示重试按钮。
全局错误展示
全局错误主要用于展示系统级别的错误,如网络连接问题、配置错误等:
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>
);
消息级别错误展示(推荐)
当用户消息发送失败时,错误信息会被挂载到对应的用户消息上。这样可以清楚地知道是哪条消息出现了问题,提供更精准的错误提示:
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. 优先使用消息级错误处理
推荐优先使用消息级错误处理,因为它能提供更精准的错误定位:
// 推荐做法
{
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. 提供重试机制
为用户提供重试功能,提升用户体验:
const retryMessage = (failedMessage: Message) => {
// 重新设置输入内容和文件
setInput(failedMessage.content);
setFiles(failedMessage.files || []);
// 移除失败的消息
const newMessages = messages.filter((msg) => msg.id !== failedMessage.id);
setMessages(newMessages);
// 重新发送
chat();
};
4. 错误信息的本地化
根据实际业务需求,可以对错误信息进行本地化处理:
const getErrorMessage = (error: any) => {
if (error.statusCode === 404) {
return '服务暂时不可用,请稍后重试';
}
if (error.statusCode === 500) {
return '服务器内部错误,请联系管理员';
}
return error.message || '未知错误';
};