Skip to content

语法糖

本文档展示如何使用 SDK 提供的 safesqlSafe 语法糖,简化错误处理代码。

💡 版本要求


传统写法:繁琐且容易出错

场景一:普通 API 调用

TypeScript
// 📌 传统写法:两层嵌套
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 查询

TypeScript
// 📌 传统写法:三层检查
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 嵌套访问
  • 代码重复,容易遗漏检查

场景三:并发请求

TypeScript
// 📌 传统写法:错误处理分散
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 错误处理

TypeScript
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 行代码

并发请求:结构统一

TypeScript
// ✅ 简洁:统一处理
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 优化

TypeScript
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 查询

TypeScript
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. 优先使用语法糖

TypeScript
// 💡 语法糖:简洁
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

TypeScript
// 💡 语法糖:一次检查
const { data, error } = await sqlSafe(() => client.sql.execute(...));

// ❌ 避免:容易遗漏业务检查
const result = await client.sql.execute(...);
result.execResult?.forEach(...); // 可能 execSuccess=false

3. 早期返回模式

TypeScript
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. 并发请求统一处理

TypeScript
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

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

interface SafeResult<T> {
  data: T | null;
  error: LovrabetError | null;
}

sqlSafe

TypeScript
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 文档

基于飞书知识库同步生成,内容以飞书源文档为准