标准异常类库,用于在应用中创建结构化的异常。
@buka/exception 提供 Exception 基类,用于定义和抛出结构化异常,支持错误分类、模块标识、序列号及详细信息。
通常配合 @buka/error-codes 使用,以确保错误编码的一致性。
pnpm add @buka/exception使用 Exception 基类创建项目特定的异常类:
import { Exception } from "@buka/exception";
class ValidationException extends Exception {
constructor(message: string, details = []) {
super({
message,
category: 1, // 验证错误类别
moduleId: 1,
sequenceId: 1,
details,
});
}
}
throw new ValidationException("Validation failed");通过实现添加异常详情
通过传递 details 提供错误的详细信息。可以是普通对象,也可以实现 ExceptionDetail 接口来规范化结构:
import { type ExceptionDetail } from '@buka/exception'
// 方法 1:直接传递普通对象
throw new ValidationException('Validation failed', {
type: 'field_validation',
field: 'email',
message: 'Invalid format'
})
// 方法 2:使用 ExceptionDetail 接口规范化
class FieldValidationDetail implements ExceptionDetail {
readonly type = 'field_validation'
constructor(
public readonly field: string,
public readonly message: string
) {}
}
throw new ValidationException(
'Validation failed',
new FieldValidationDetail('email', 'Invalid format')
)
// 多个详情
throw new ValidationException('Data validation failed', [
new FieldValidationDetail('email', 'Invalid format'),
new FieldValidationDetail('age', 'Must be positive')
]
## 异常捕获处理
```typescript
try {
// 业务代码
} catch (error) {
if (error instanceof ValidationException) {
console.log(`Error: ${error.message}`)
console.log(`Category: ${error.category}`)
console.log(`Module: ${error.moduleId}`)
console.log(`Details:`, error.details)
}
}异常基类,继承自 ts-custom-error 的 CustomError。
interface ExceptionOptions {
message: string; // 错误消息
category: number; // 错误类别
moduleId: number; // 模块 ID
sequenceId: number; // 序列 ID
details?: ExceptionDetail | ExceptionDetail[]; // 可选的错误详情
}message- 错误消息category- 错误类别标识moduleId- 模块标识sequenceId- 序列号details- 错误详情数组(只读)
自定义错误详情的接口。
interface ExceptionDetail {
readonly type: string; // 详情类型
[key: string]: unknown; // 允许附加属性
}建议结合 @buka/error-codes 来管理错误码。ErrorCode 中包含了 systemId、category、moduleId 和 sequenceId,而 Exception 不包含 systemId 属性。这是因为 systemId 是应用系统级别的标识,应该由业务系统在统一的上下文中注入(如中间件、拦截器等),而非在异常定义时指定。这样设计使得二方包可以独立使用,而业务系统负责在异常处理层统一补充 systemId 信息。
定义业务系统的模块枚举和异常类:
import { Exception, type ExceptionOptions } from "@buka/exception";
import { ErrorCode, ErrorCategory } from "@buka/error-codes";
// 定义模块枚举
enum ErrorModuleId {
USER_SERVICE = 100,
ORDER_SERVICE = 101,
PAYMENT_SERVICE = 102,
}
// 定义异常类
class UserNotFoundException extends Exception {
constructor(userId: string) {
super({
message: `User ${userId} not found`,
category: ErrorCategory.BUSINESS,
moduleId: ErrorModuleId.USER_SERVICE,
sequenceId: 1,
details: {
type: "not_found",
resource: "user",
id: userId,
},
});
}
}
class OrderValidationException extends Exception {
constructor(message: string, details: object) {
super({
message,
category: ErrorCategory.VALIDATION,
moduleId: ErrorModuleId.ORDER_SERVICE,
sequenceId: 1,
details,
});
}
}