跳到主要内容

错误处理

版本要求

AI 友好的错误处理架构需要 @lovrabet/sdk v1.2.5 及以上版本。

Lovrabet SDK 采用 AI 友好的错误处理架构,专为 Vibe Coding(AI 辅助编程)场景设计。当你在 Cursor、Claude Code、Copilot 等 AI 编程工具中使用 SDK 时,错误信息能够被 AI 直接理解,并自动提供修复建议。

设计理念

为什么需要 AI 友好的错误?

传统的错误处理只关注人类开发者:

// 传统错误 - AI 难以理解上下文
Error: "project_id列不能为空"

在 Vibe Coding 场景下,AI 需要更多上下文才能帮你修复问题:

  • 这是什么类型的错误?参数错误?权限问题?
  • 具体是哪个字段出了问题?
  • 应该如何修复?有什么建议?
  • 如何获取正确的字段信息?

Lovrabet SDK 的 AI 友好架构正是为解决这些问题而设计。

架构目标

  1. 错误可被 AI 理解 - 结构化的错误信息,包含错误类型、原因、状态码
  2. 提供修复建议 - 针对不同错误类型,给出具体的修复方向
  3. 引导 AI 使用工具 - 当需要更多信息时,引导 AI 调用 MCP 工具获取
  4. 支持自动修复 - AI 可以根据建议自动修改代码

LovrabetError 类型

SDK 所有错误都使用统一的 LovrabetError 类型抛出:

import { LovrabetError } from "@lovrabet/sdk";

try {
await client.models.users.create({ name: "张三" });
} catch (error) {
if (error instanceof LovrabetError) {
console.log(error.message); // 错误消息
console.log(error.code); // 错误码
console.log(error.status); // HTTP 状态码
console.log(error.description); // AI 友好的详细描述 ⭐
console.log(error.response); // 服务端原始响应
console.log(error.cause); // 原始错误(v1.2.10+)
}
}

错误属性详解

属性类型用途AI 如何使用
messagestring简短错误消息快速了解问题
codestring错误码判断错误类别
statusnumberHTTP 状态码判断是客户端还是服务端问题
descriptionstringAI 友好的详细描述理解错误原因、获取修复建议
responseobject原始响应需要时可获取更多细节
causeunknown原始错误对象(v1.2.10+)追溯错误源头

AI 友好的 description 字段

description 是 SDK 专为 AI 设计的核心字段(v1.2.5+),它包含:

  1. 错误原因 - 服务端返回了什么错误
  2. 错误分类 - 这是什么类型的错误
  3. 状态码 - HTTP 状态码是多少
  4. 修复建议 - 针对性的修复方向

description 的结构

服务端返回错误: {错误消息}。错误类型: {类型}。状态码: {status}。建议: {具体建议}

这种结构化的自然语言格式,让 AI 能够:

  • 解析出关键信息(字段名、错误类型)
  • 理解问题的严重程度
  • 按照建议采取行动

Vibe Coding 实战场景

以下展示 AI 如何利用 description 自动修复错误。

场景一:字段名拼写错误

你在 Cursor 中写代码:

await client.models.users.create({
naem: "张三", // 拼写错误
phone: "13800138000"
});

运行后 SDK 抛出错误:

LovrabetError {
message: "naem列不存在",
code: "SERVER_ERROR",
status: 400,
description: "服务端返回错误: naem列不存在。错误类型: 参数错误。状态码: 400。建议: 字段 \"naem\" 不存在,请检查字段名是否拼写正确; 使用 MCP 工具获取数据集的正确字段列表"
}

AI 的理解过程:

  1. 解析 description,发现是"参数错误"
  2. 识别出问题字段是 naem
  3. 看到建议"检查字段名是否拼写正确"
  4. 推断 naem 可能是 name 的拼写错误
  5. 自动修复代码
// AI 自动修复后
await client.models.users.create({
name: "张三", // 已修复
phone: "13800138000"
});

场景二:缺少必填字段

await client.models.orders.create({
name: "订单1",
amount: 100
});

SDK 错误信息:

LovrabetError {
message: "project_id列不能为空",
code: "SERVER_ERROR",
status: 400,
description: "服务端返回错误: project_id列不能为空。错误类型: 参数错误。状态码: 400。建议: 字段 \"project_id\" 是必填项,请确保传递该字段"
}

AI 的处理方式:

  1. 识别出 project_id 是必填项
  2. 检查当前代码,确认该字段确实缺失
  3. 可能通过 MCP 工具查询数据集结构,了解 project_id 的类型
  4. 提示用户补充该字段,或根据上下文自动补充

场景三:权限/登录问题

await client.models.users.filter();

SDK 错误信息:

LovrabetError {
message: "权限不足",
code: "SERVER_ERROR",
status: 401,
description: "服务端返回错误: 权限不足。错误类型: 202。状态码: 401。建议: 检查用户登录态是否过期,需要重新登录; 检查 appCode 是否有访问该数据集的权限; 确保使用 HTTPS 协议访问; 检查是否存在跨域问题(CORS)"
}

AI 的排查方向:

  1. 看到 401 状态码,识别为认证问题
  2. 根据建议,依次排查:
    • 登录态是否过期
    • appCode 权限配置
    • HTTPS 协议
    • CORS 配置
  3. 给用户提供具体的排查步骤

与 MCP 工具协同

description 中会引导 AI 使用 MCP 工具获取更多信息:

建议: 字段 "xxx" 不存在,请检查字段名是否拼写正确; 使用 MCP 工具获取数据集的正确字段列表

当 AI 看到这个建议时,会调用 MCP 工具:

// AI 调用 MCP 工具
const datasetInfo = await mcp.tools.get_dataset_detail({
datasetCode: "users"
});

// 获取正确的字段列表
const fields = datasetInfo.fields;
// ["id", "name", "phone", "email", "created_at", ...]

然后 AI 就能:

  • 找到正确的字段名
  • 了解哪些字段是必填的
  • 知道字段的类型和格式要求

这种 SDK + MCP 的协同架构,让 AI 能够完整地理解和解决问题。


错误码参考

客户端错误码

错误码说明description 内容
MODEL_NOT_FOUND模型不存在列出所有可用模型(datasetCode、alias、name)
MODEL_INDEX_OUT_OF_RANGE模型索引越界提供有效索引范围
CONFIG_NOT_FOUND配置不存在列出已注册的配置名称
APP_CODE_REQUIRED缺少 appCode提供配置示例
TIMEOUT请求超时当前超时时间、优化建议
OPENAPI_AUTH_PARAMS_MISSINGOpenAPI 认证参数缺失列出缺失的参数

服务端错误码

错误类型HTTP 状态码description 内容
参数错误400字段修复建议(必填、拼写、格式)
权限不足401登录态、appCode、HTTPS、CORS 检查建议
其他错误各种基本信息(错误类型、消息、状态码)

safe 函数:无 try-catch 错误处理 v1.2.10+

除了传统的 try-catch 模式,SDK 还提供了 safe 函数,让你无需 try-catch 即可优雅地处理错误。

基本用法

import { safe } from "@lovrabet/sdk";

// 新风格:无 try-catch
const { data, error } = await safe(() =>
client.models.users.filter({ where: { status: 'active' } })
);

if (error) {
console.error("查询失败:", error.message, error.description);
return;
}

// 使用 data
console.log("用户列表:", data);

与 try-catch 对比

方面try-catch 模式safe 模式
代码量较多(try-catch 嵌套)较少(解构赋值)
嵌套层级容易产生嵌套地狱扁平化
错误类型需要手动判断总是 LovrabetError
早期返回需要 throw 或 return直接 return
适用场景复杂错误处理逻辑简单的条件判断

使用场景对比

try-catch 适合复杂场景:

try {
const user = await client.models.users.getOne(userId);
const orders = await client.models.orders.filter({ userId });
const stats = await client.api.executeSql('user-stats', { userId });
return { user, orders, stats };
} catch (error) {
if (error instanceof LovrabetError) {
if (error.status === 404) {
throw new Error("用户不存在");
} else if (error.status === 403) {
throw new Error("无权访问");
}
}
throw error;
}

safe 适合简单场景:

// 场景 1:单个 API 调用
const { data, error } = await safe(() => client.models.users.getOne(userId));
if (error) return { success: false, error: error.message };
return { success: true, data };

// 场景 2:顺序操作
const result1 = await safe(() => client.models.users.getOne(userId));
if (result1.error) return { error: result1.error.message };

const result2 = await safe(() => client.models.orders.filter({ userId }));
if (result2.error) return { error: result2.error.message };

return { user: result1.data, orders: result2.data };

类型定义

interface SafeResult<T> {
data: T | null; // 成功时的数据
error: LovrabetError | null; // 失败时的错误
}

function safe<T>(
fn: Promise<T> | (() => Promise<T>)
): Promise<SafeResult<T>>;

高级用法

处理并发请求:

const [usersResult, ordersResult, statsResult] = await Promise.all([
safe(() => client.models.users.filter()),
safe(() => client.models.orders.filter()),
safe(() => client.api.executeSql('daily-stats')),
]);

// 检查各自的结果
if (usersResult.error) {
console.error("获取用户失败:", usersResult.error.message);
}
if (ordersResult.error) {
console.error("获取订单失败:", ordersResult.error.message);
}
if (statsResult.error) {
console.error("获取统计失败:", statsResult.error.message);
}

// 使用成功的返回值
console.log("用户:", usersResult.data);
console.log("订单:", ordersResult.data);
console.log("统计:", statsResult.data);

封装错误处理工具:

import { safe, LovrabetError } from "@lovrabet/sdk";

// 统一的 API 调用处理
async function handleApiCall<T>(
operation: () => Promise<T>,
errorMessage: string
): Promise<T> {
const { data, error } = await safe(operation);

if (error) {
// 记录错误
console.error(`${errorMessage}:`, error.message, error.description);
// 可以在这里添加日志上报
throw new Error(errorMessage);
}

return data!;
}

// 使用
const users = await handleApiCall(
() => client.models.users.filter({ status: 'active' }),
"获取活跃用户失败"
);

向后兼容

safe 函数不影响现有代码,两种模式可以共存:

// 旧代码继续工作
try {
const data = await client.models.users.filter();
console.log(data);
} catch (e) {
console.error(e);
}

// 新代码也可以用 safe
const { data, error } = await safe(() => client.models.users.filter());
if (error) {
console.error(error);
} else {
console.log(data);
}

最佳实践

让 AI 能看到错误信息

在 Vibe Coding 时,确保错误信息能被 AI 工具捕获:

try {
await client.models.users.create(formData);
} catch (error) {
if (error instanceof LovrabetError) {
// 输出 description,AI 工具会读取控制台
console.error("SDK Error:", error.description);

// 或者直接抛出,让 AI 看到完整堆栈
throw error;
}
}

全局错误处理

配置全局错误处理,统一输出 AI 友好的信息:

const client = createClient({
appCode: "your-app-code",
options: {
onError: (error: LovrabetError) => {
// 输出 AI 友好的描述
console.error("[Lovrabet SDK Error]", error.description);

// 401 自动跳转登录
if (error.status === 401) {
window.location.href = "/login";
}
},
},
models: [
{ tableName: "users", datasetCode: "xxx", alias: "users" },
],
});

开发环境增强输出

开发环境下输出更多信息:

function handleError(error: LovrabetError) {
if (process.env.NODE_ENV === "development") {
console.group("LovrabetError Debug Info");
console.log("Message:", error.message);
console.log("Code:", error.code);
console.log("Status:", error.status);
console.log("Description:", error.description);
console.log("Response:", JSON.stringify(error.response, null, 2));
console.groupEnd();
}
}

错误类型判断

按 HTTP 状态码

if (error instanceof LovrabetError) {
switch (error.status) {
case 400:
// 参数错误 - AI 可以根据 description 自动修复
break;
case 401:
// 认证失败 - 需要重新登录
break;
case 403:
// 权限不足 - 检查 appCode 配置
break;
case 500:
// 服务器错误 - 需要联系运维
break;
}
}

按错误码

if (error instanceof LovrabetError) {
switch (error.code) {
case "MODEL_NOT_FOUND":
// 查看 description 获取可用模型列表
console.log(error.description);
break;
case "SERVER_ERROR":
// 查看 description 获取具体原因和建议
console.log(error.description);
break;
}
}

总结

Lovrabet SDK 的 AI 友好错误处理架构:

特性说明
统一错误类型所有错误都是 LovrabetError,便于统一处理
AI 可理解的 description包含错误原因、类型、建议,AI 可直接解析
针对性修复建议不同错误类型提供不同的修复方向
MCP 工具协同引导 AI 使用 MCP 获取更多信息
支持自动修复AI 可以根据信息自动修改代码

在 Vibe Coding 时代,好的错误信息不仅要让人能看懂,更要让 AI 能理解并帮你解决问题。

更多高级错误处理模式(重试机制、断路器等),请参考 高级功能