Exception handler for koatty.
npm install koatty_exception



koatty_exception 是 Koatty 框架的异常处理模块,提供了统一的错误处理机制、响应格式化和多协议支持。
- 🎯 统一异常处理 - 提供标准化的异常处理机制
- 🔗 链式调用 - 支持方法链式调用,代码更优雅
- 🌐 多协议支持 - 支持 HTTP、gRPC、WebSocket 多种协议
- 📊 可观测性 - 集成 OpenTelemetry 链路追踪
- 🔧 高度可配置 - 支持自定义日志格式、错误响应格式等
- 📝 TypeScript 支持 - 完整的类型定义和类型安全
- 🚀 零依赖核心 - 核心功能无外部依赖
- 📦 装饰器模式 - 使用 @ExceptionHandler 装饰器注册异常处理器
``bash
npm install koatty_exception
🚀 快速开始
$3
`typescript
import { Exception, Output, CommonErrorCode } from 'koatty_exception';// 创建基础异常
const error = new Exception('用户未找到', CommonErrorCode.RESOURCE_NOT_FOUND, 404);
// 链式调用设置异常属性
const customError = new Exception('验证失败')
.setCode(CommonErrorCode.VALIDATION_ERROR)
.setStatus(400)
.setContext({
requestId: 'req-123',
path: '/api/users',
method: 'POST'
});
// 使用 Output 类格式化响应
const successResponse = Output.ok('操作成功', { id: 1, name: '张三' });
const errorResponse = Output.fail('操作失败', null, 1001);
`$3
`typescript
import { Exception, ExceptionHandler } from 'koatty_exception';
import { KoattyContext } from 'koatty_core';@ExceptionHandler()
export class ValidationException extends Exception {
constructor(message: string, field?: string) {
super(message, CommonErrorCode.VALIDATION_ERROR, 400);
if (field) {
this.setContext({ field });
}
}
async handler(ctx: KoattyContext): Promise {
// 自定义处理逻辑
const response = {
error: 'VALIDATION_ERROR',
message: this.message,
field: this.context?.field,
timestamp: new Date().toISOString()
};
ctx.status = this.status;
ctx.type = 'application/json';
return ctx.res.end(JSON.stringify(response));
}
}
// 使用自定义异常
throw new ValidationException('邮箱格式不正确', 'email');
`$3
`typescript
import { setExceptionConfig } from 'koatty_exception';// 配置异常处理行为
setExceptionConfig({
enableStackTrace: process.env.NODE_ENV !== 'production',
logFormat: 'json',
maxStackLength: 1000,
customErrorFormat: (error) => ({
errorId: generateErrorId(),
type: error.constructor.name,
message: error.message,
timestamp: new Date().toISOString()
})
});
`📚 API 文档
$3
#### 构造函数
`typescript
constructor(message: string, code?: number, status?: number, stack?: string, span?: Span)
`#### 方法
##### setCode(code: number): this
设置错误代码(必须为非负整数)
##### setStatus(status: number): this
设置 HTTP 状态码(必须在 100-599 范围内)
##### setMessage(message: string): this
设置错误消息
##### setContext(context: Partial): this
设置错误上下文信息
##### setSpan(span: Span): this
设置 OpenTelemetry 跟踪 span
##### async handler(ctx: KoattyContext): Promise
处理异常并返回响应
##### toJSON(): object
将异常转换为普通对象
$3
#### 静态方法
##### ok(message: string | JsonResult, data?: T, code?: number): JsonResult
创建成功响应
`typescript
// 基础用法
Output.ok('操作成功', { id: 1 });
// 结果: { code: 0, message: '操作成功', data: { id: 1 } }// 自定义代码
Output.ok('创建成功', newUser, 201);
`##### fail(err?: Error | CodeError | string | unknown, data?: T, code?: number): JsonResult
创建失败响应
`typescript
// 使用错误对象
Output.fail(new Error('数据库连接失败'));// 使用字符串
Output.fail('参数无效', null, 1001);
// 使用 CodeError 对象
Output.fail({ code: 1002, message: '权限不足', data: { required: 'admin' } });
`##### paginate(items: T[], total: number, page: number, pageSize: number, message?: string): JsonResult
创建分页响应
`typescript
const users = [/ 用户列表 /];
const response = Output.paginate(users, 100, 2, 10, '用户列表');
// 包含 pagination 信息:{ total, page, pageSize, totalPages, hasNext, hasPrev }
`##### withMeta(message: string, data: T, meta?: Record, code?: number): JsonResult
创建带元数据的响应
`typescript
Output.withMeta('查询成功', userData, {
version: '1.0',
executionTime: 120,
cached: true
});
`$3
#### prevent(): Promise
创建一个用于阻止下一步处理的 Promise
#### isPrevent(err: unknown): err is Error
检查是否为阻止处理的错误
#### isException(err: unknown): err is Exception
类型保护函数,检查是否为 Exception 实例
#### toSafeError(err: unknown): Error
将任意值转换为安全的 Error 对象
#### isNetworkError(err: unknown): boolean
检查是否为网络相关错误
🔧 配置选项
`typescript
interface ExceptionConfig {
enableStackTrace?: boolean; // 是否启用堆栈跟踪(默认:非生产环境启用)
logFormat?: 'json' | 'text'; // 日志格式(默认:json)
customErrorFormat?: (error: Exception) => any; // 自定义错误格式化函数
maxStackLength?: number; // 最大堆栈长度(默认:1000)
}
`🏗️ 高级用法
$3
`typescript
@ExceptionHandler()
export class BusinessException extends Exception {
constructor(message: string, businessCode: string) {
super(message, CommonErrorCode.GENERAL_ERROR, 400);
this.setContext({ businessCode });
}
}@ExceptionHandler()
export class AuthenticationException extends Exception {
constructor(message: string = '身份验证失败') {
super(message, CommonErrorCode.AUTHENTICATION_ERROR, 401);
}
async handler(ctx: KoattyContext): Promise {
// 清除认证信息
ctx.cookies.set('token', null);
return super.handler(ctx);
}
}
`$3
`typescript
export class ErrorCollector {
private static errors: Map = new Map();
static record(error: Exception): void {
const key = ${error.constructor.name}:${error.code};
this.errors.set(key, (this.errors.get(key) || 0) + 1);
}
static getStats(): Record {
return Object.fromEntries(this.errors);
}
}// 在异常处理器中使用
@ExceptionHandler()
export class MonitoredException extends Exception {
async handler(ctx: KoattyContext): Promise {
ErrorCollector.record(this);
return super.handler(ctx);
}
}
`$3
`typescript
import { prevent, isPrevent } from 'koatty_exception';async function processData() {
try {
const shouldStop = await checkCondition();
if (shouldStop) {
await prevent(); // 阻止后续处理
}
// 继续处理...
} catch (error) {
if (isPrevent(error)) {
console.log('处理被阻止');
return;
}
throw error; // 重新抛出其他错误
}
}
`🧪 测试
`bash
运行所有测试
npm test运行测试并生成覆盖率报告
npm run test:cov运行 ESLint 检查
npm run eslint
`📊 错误代码参考
`typescript
export enum CommonErrorCode {
SUCCESS = 0, // 成功
GENERAL_ERROR = 1, // 通用错误
VALIDATION_ERROR = 1001, // 验证失败
AUTHENTICATION_ERROR = 1002, // 身份验证失败
AUTHORIZATION_ERROR = 1003, // 权限不足
RESOURCE_NOT_FOUND = 1004, // 资源未找到
RESOURCE_CONFLICT = 1005, // 资源冲突
RATE_LIMIT_EXCEEDED = 1006, // 请求频率超限
INTERNAL_SERVER_ERROR = 1007, // 内部服务器错误
SERVICE_UNAVAILABLE = 1008, // 服务不可用
TIMEOUT_ERROR = 1009, // 超时错误
NETWORK_ERROR = 1010 // 网络错误
}
`🤝 贡献
欢迎贡献代码!请查看 贡献指南 了解详情。
$3
1. Fork 项目
2. 创建特性分支 (
git checkout -b feature/amazing-feature)
3. 提交更改 (git commit -m 'Add some amazing feature')
4. 推送到分支 (git push origin feature/amazing-feature`)本项目基于 BSD-3-Clause 许可证开源。
- Koatty 框架
- API 文档
- 更新日志
- 问题反馈
感谢所有为这个项目做出贡献的开发者!