语法糖
本文档展示如何使用 SDK 提供的 safe 和 sqlSafe 语法糖,简化错误处理代码。
版本要求
safe函数需要@lovrabet/sdkv1.3.0 及以上版本sqlSafe函数需要@lovrabet/sdkv1.3.0 及以上版本
传统写法:繁琐且容易出错
场景一:普通 API 调用
// 📌 传统写法:两层嵌套
try {
const users = await client.models.users.filter();
console.log(users);
} catch (error) {
if (error instanceof LovrabetError) {
console.error(error.message, error.description);
} else {
console.error(error);
}
}
问题:
- try-catch 增加嵌套层级
- 需要手动判断 error 类型
- 代码量大,可读性差
场景二:SQL 查询
// 📌 传统写法:三层检查
try {
const result = await client.sql.execute({ sqlCode: "xxx" });
// 业务层检查
if (result.execSuccess && result.execResult) {
console.log(`查询到 ${result.execResult.length} 条记录`);
result.execResult.forEach((row) => console.log(row));
} else {
console.error("SQL 执行失败");
}
} catch (error) {
if (error instanceof LovrabetError) {
console.error("请求失败:", error.message);
}
}
问题:
- HTTP 错误 + 业务逻辑错误,两层检查
execResult嵌套访问- 代码重复,容易遗漏检查
场景三:并发请求
// 📌 传统写法:错误处理分散
const [users, orders, stats] = await Promise.all([
client.models.users.filter().catch((e) => ({ error: e })),
client.models.orders.filter().catch((e) => ({ error: e })),
client.sql.execute({ sqlCode: "stats" }).catch((e) => ({ error: e })),
]);
if (users.error) console.error("获取用户失败");
if (orders.error) console.error("获取订单失败");
if (stats.error) {
console.error("获取统计失败");
} else {
if (!stats.data.execSuccess) {
console.error("SQL 执行失败");
}
}
问题:
- 每个请求都要单独处理错误
- SQL 的业务状态检查更复杂
- 代码结构不统一
使用 safe:简化普通 API 错误处理
import { safe } from "@lovrabet/sdk";
// 💡 语法糖:一次检查
const { data, error } = await safe(() => client.models.users.filter());
if (error) {
console.error("查询失败:", error.message, error.description);
return;
}
// data 直接是结果数据
console.log(data);
对比:
| 传统 | safe |
|---|---|
| try-catch 嵌套 | 平级解构 |
| 手动判断 error 类型 | 自动转换为 LovrabetError |
| 5-10 行代码 | 3 行代码 |
并发请求:结构统一
// ✅ 简洁:统一处理
const [usersResult, ordersResult, statsResult] = await Promise.all([
safe(() => client.models.users.filter()),
safe(() => client.models.orders.filter()),
safe(() => client.sql.execute({ sqlCode: "stats" })),
]);
// 逐个检查
if (usersResult.error) console.error("用户失败");
if (ordersResult.error) console.error("订单失败");
if (statsResult.error) console.error("统计失败");
// 使用成功的数据
usersResult.data?.forEach((user) => console.log(user));
使用 sqlSafe:专为 SQL 优化
import { sqlSafe } from "@lovrabet/sdk";
// ✅ 简洁:一次检查,直接拿到数组
const { data, error } = await sqlSafe(() =>
client.sql.execute({ sqlCode: "user-stats" })
);
if (!error) {
// data 直接是查询结果数组
console.log(`查询到 ${data.length} 条记录`);
data.forEach((row) => console.log(row));
}
对比:
| 传统 | sqlSafe |
|---|---|
| try-catch + execSuccess 检查 | 一次 if 判断 |
| 访问 result.execResult | 直接访问 data |
| 10-15 行代码 | 5 行代码 |
带类型的 SQL 查询
interface UserStat {
id: number;
name: string;
login_count: number;
}
const { data, error } = await sqlSafe<UserStat>(() =>
client.sql.execute<UserStat>({ sqlCode: "user-stats" })
);
if (error) return;
// data 是 UserStat[],类型安全
data.forEach((stat) => {
console.log(`${stat.name}: ${stat.login_count} 次登录`);
});
语法糖对比表
| 场景 | 传统写法(代码行数) | 语法糖(代码行数) |
|---|---|---|
| 普通 API 错误处理 | 8-10 行 | 3 行 |
| SQL 查询完整处理 | 15-20 行 | 5 行 |
| 并发请求 | 30+ 行 | 10 行 |
| 类型安全访问 | 需要类型断言 | 自动推断 |
最佳实践
1. 优先使用语法糖
// 💡 语法糖:简洁
const { data, error } = await safe(() => api.call());
if (error) return;
// 📌 传统写法:繁琐
try {
const data = await api.call();
} catch (e) {
if (e instanceof LovrabetError) {
// ...
}
}
2. SQL 必须用 sqlSafe
// 💡 语法糖:一次检查
const { data, error } = await sqlSafe(() => client.sql.execute(...));
// ❌ 避免:容易遗漏业务检查
const result = await client.sql.execute(...);
result.execResult?.forEach(...); // 可能 execSuccess=false
3. 早期返回模式
const fetchUsers = async () => {
const { data, error } = await safe(() => client.models.users.filter());
if (error) return { success: false, error: error.message };
return { success: true, data };
};
4. 并发请求统一处理
const loadDashboard = async () => {
const [users, orders, stats] = await Promise.all([
sqlSafe(() => client.sql.execute({ sqlCode: "users" })),
sqlSafe(() => client.sql.execute({ sqlCode: "orders" })),
sqlSafe(() => client.sql.execute({ sqlCode: "stats" })),
]);
if (users.error || orders.error || stats.error) {
console.error("数据加载失败");
return;
}
return {
users: users.data!,
orders: orders.data!,
stats: stats.data!,
};
};
API 参考
safe
function safe<T>(fn: Promise<T> | (() => Promise<T>)): Promise<SafeResult<T>>;
interface SafeResult<T> {
data: T | null;
error: LovrabetError | null;
}
sqlSafe
function sqlSafe<T>(
fn: Promise<SqlExecuteResult<T>> | (() => Promise<SqlExecuteResult<T>>)
): Promise<SqlSafeResult<T>>;
interface SqlSafeResult<T> {
data: T[] | null;
error: LovrabetError | null;
}
相关文档
- 错误处理指南 - 详细的错误处理机制
- SQL API 参考 - SQL API 详细说明
- API 参考手册 - 完整 API 文档