跳到主要内容

错误处理


错误处理

ℹ️ 版本要求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 如何使用

message

string

简短错误消息

快速了解问题

code

string

错误码

判断错误类别

status

number

HTTP 状态码

判断是客户端还是服务端问题

description

string

AI 友好的详细描述

理解错误原因、获取修复建议

response

object

原始响应

需要时可获取更多细节

cause

unknown

原始错误对象(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_MISSING

OpenAPI 认证参数缺失

列出缺失的参数

服务端错误码

错误类型

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 能理解并帮你解决问题。

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