错误处理
VentoStack 提供了一套完整的错误类型层级,方便在路由和中间件中抛出语义明确的错误。
内置错误类型
Section titled “内置错误类型”import { VentoStackError, // 基类 ClientError, // 4xx 错误基类 ServerError, // 5xx 错误基类 NotFoundError, // 404 ValidationError, // 422(通常) UnauthorizedError, // 401 ForbiddenError, // 403} from "@ventostack/core";VentoStackError├── ClientError (4xx)│ ├── NotFoundError (404)│ ├── ValidationError (422)│ ├── UnauthorizedError (401)│ └── ForbiddenError (403)└── ServerError (5xx)import { NotFoundError, ValidationError, UnauthorizedError } from "@ventostack/core";
router.get("/users/:id<int>", async (ctx) => { const user = await db.query(UserModel).where("id", "=", ctx.params.id).get();
if (!user) { throw new NotFoundError("用户不存在"); }
return ctx.json(user);});
router.post("/users", async (ctx) => { const body = await ctx.body<{ email: string }>();
if (!body.email || !body.email.includes("@")) { throw new ValidationError("邮箱格式无效", { field: "email" }); }
const user = await createUser(body); return ctx.json(user, 201);});全局错误处理中间件
Section titled “全局错误处理中间件”建议在应用入口注册全局错误处理中间件:
import { VentoStackError, ClientError, ServerError } from "@ventostack/core";import type { Middleware } from "@ventostack/core";
const errorHandler: Middleware = async (ctx, next) => { try { await next(); } catch (err) { if (err instanceof VentoStackError) { return ctx.json( { error: err.message, code: err.code, ...(err instanceof ValidationError ? { details: err.details } : {}) }, err.statusCode ); }
// 未预期的错误 console.error("Unhandled error:", err); return ctx.json({ error: "内部服务器错误" }, 500); }};
const app = createApp({ port: 3000 });app.use(errorHandler); // 第一个注册,捕获所有后续错误自定义错误类型
Section titled “自定义错误类型”import { ClientError } from "@ventostack/core";
class PaymentRequiredError extends ClientError { constructor(message: string) { super(message, 402, "PAYMENT_REQUIRED"); }}
class RateLimitError extends ClientError { constructor(retryAfter: number) { super("请求过于频繁,请稍后重试", 429, "RATE_LIMIT_EXCEEDED"); this.retryAfter = retryAfter; }
readonly retryAfter: number;}
// 使用router.post("/checkout", async (ctx) => { const user = ctx.state.user; if (!user.hasPlan) { throw new PaymentRequiredError("需要升级到付费计划"); } // ...});错误类构造参数
Section titled “错误类构造参数”// VentoStackError 基类new VentoStackError(message: string, statusCode: number, code?: string)
// 预定义错误new NotFoundError(message?: string) // 404, "NOT_FOUND"new UnauthorizedError(message?: string) // 401, "UNAUTHORIZED"new ForbiddenError(message?: string) // 403, "FORBIDDEN"new ValidationError(message: string, details?: unknown) // 422, "VALIDATION_ERROR"