@seed-fe/exception-handler
v1.0.0
Published
A library that handles global exceptions.
Downloads
4
Maintainers
Readme
@seed-fe/exception-handler
一个现代化的全局异常处理库,支持多种异常来源的统一捕获和处理。
特性
- 内置 JavaScript 标准异常捕获(
error、unhandledrejection) - 支持第三方框架异常接入(Vue、React 等)
- 条件化异常处理,支持多处理器协作
- 并行/串行处理模式
- Leading/Trailing 钩子支持
- 动态处理器管理
- Symbol/String 联合类型名称支持
- 元数据支持,增强异常上下文
- 完整的 TypeScript 类型支持
安装
# 使用 npm
npm install @seed-fe/exception-handler
# 使用 yarn
yarn add @seed-fe/exception-handler
# 使用 pnpm (推荐)
pnpm add @seed-fe/exception-handler基础使用
快速开始
import { createExceptionCatcher } from '@seed-fe/exception-handler';
// 创建异常捕获器 - 现在支持所有参数在一个配置对象中
const catcher = createExceptionCatcher({
handlers: [
{
name: 'logger',
condition: () => true,
handler: async (context) => {
console.log('捕获到异常:', context.error.message);
}
}
],
enableStandardCapture: true, // 启用标准异常捕获
enableConsoleError: true // 启用控制台错误输出
});
// 启动标准异常监听
catcher.start();
// 手动捕获异常
catcher.captureException(new Error('自定义错误'), {
source: 'user-action',
metadata: { userId: '123', page: '/dashboard' }
});直接使用构造函数
import { ExceptionCatcher } from '@seed-fe/exception-handler';
// 也可以直接使用构造函数,支持相同的配置参数
const catcher = new ExceptionCatcher({
handlers: [
{
name: 'logger',
condition: () => true,
handler: async (context) => {
console.log('捕获到异常:', context.error.message);
}
}
],
leadingHook: {
handler: async () => ({ userId: getCurrentUserId() })
},
enableStandardCapture: true
});
catcher.start();条件化处理
const handlers = [
{
name: 'error-reporter',
condition: (context) => context.error.message.includes('critical'),
handler: async (context) => {
// 只处理关键错误
await reportToService(context.error);
}
},
{
name: 'logger',
condition: () => true,
handler: async (context) => {
// 记录所有错误
console.log(context.error);
}
}
];
catcher.setHandlers(handlers);约定如果 name 为 __fallback__ 的处理器,当没有其他处理器处理异常时使用。
并行/串行处理
处理器可以配置 mode 属性,决定是并行执行还是串行执行。默认是串行执行。
mode: 'parallel'并行执行,同时执行,看到相同的初始上下文mode: 'serial'串行执行,按顺序执行,后面的处理器可以看到前面的处理历史
const handlers = [
{
name: 'parallel-logger',
condition: () => true,
handler: async (context) => {
console.log('并行处理 1');
},
mode: 'parallel' // 并行执行
},
{
name: 'parallel-reporter',
condition: () => true,
handler: async (context) => {
console.log('并行处理 2');
},
mode: 'parallel' // 与上面同时执行
},
{
name: 'serial-cleanup',
condition: () => true,
handler: async (context) => {
console.log('串行处理,在并行处理完成后执行');
},
mode: 'serial' // 默认串行
}
];Leading/Trailing 钩子
Leading/Trailing 钩子是可选的,可以不设置。也可以在 createExceptionCatcher 时设置。
应用场景:
- 前置钩子:在所有处理器执行前运行,可以获取一些初始数据,如用户信息、页面信息等。
- 后置钩子:在所有处理器执行后运行,可以进行一些清理工作,如统计信息上报、用户通知等。
// 方式1:创建时设置钩子
const catcher = createExceptionCatcher({
handlers: [...],
leadingHook: {
handler: async (context) => {
// 在所有处理器执行前运行
return {
userId: getCurrentUserId(),
timestamp: Date.now()
};
},
breakOnError: true // 前置钩子出错时是否中断处理链
},
trailingHook: {
handler: async (context, leadingResult) => {
// 在所有处理器执行后运行
console.log('处理完成', leadingResult);
}
}
});
// 方式2:动态设置钩子
catcher.setLeadingHook({
handler: async (context) => {
return {
userId: getCurrentUserId(),
timestamp: Date.now()
};
},
breakOnError: true
});
catcher.setTrailingHook({
handler: async (context, leadingResult) => {
console.log('处理完成', leadingResult);
}
});框架集成
Vue 集成
// Vue 2
Vue.config.errorHandler = (error, vm, info) => {
catcher.captureException(error, {
source: 'vue2',
metadata: { info, componentName: vm?.$options.name }
});
};
// Vue 3
app.config.errorHandler = (error, instance, info) => {
catcher.captureException(error, {
source: 'vue3',
metadata: { info, componentName: instance?.$?.type?.name }
});
};React 集成
// Error Boundary
class ErrorBoundary extends React.Component {
componentDidCatch(error, errorInfo) {
catcher.captureException(error, {
source: 'react-boundary',
metadata: { errorInfo }
});
}
}
// 或使用 React 19+ 的新 API
const root = createRoot(container, {
onCaughtError: (error, errorInfo) => {
catcher.captureException(error, {
source: 'react-caught',
metadata: { errorInfo }
});
}
});动态管理
处理器管理
// 添加处理器
catcher.addHandler({
name: 'new-handler',
condition: () => true,
handler: async (context) => {
console.log('新处理器');
}
});
// 移除处理器
catcher.removeHandler('new-handler');
// 更新处理器
catcher.updateHandler('logger', {
name: 'logger',
condition: () => false, // 禁用
handler: async () => {}
});
// 检查处理器是否存在
if (catcher.hasHandler('logger')) {
console.log('logger 处理器存在');
}回退处理器
// 设置回退处理器,当没有其他处理器处理异常时使用
catcher.setFallbackHandler({
condition: () => true,
handler: async (context) => {
console.error('未处理的异常:', context.error);
}
});
// 移除回退处理器
catcher.removeFallbackHandler();Symbol 支持
// 使用 Symbol 避免命名冲突
const LOGGER_SYMBOL = Symbol('logger');
const REPORTER_SYMBOL = Symbol('reporter');
catcher.addHandler({
name: LOGGER_SYMBOL,
condition: () => true,
handler: async (context) => {
console.log('Symbol 处理器');
}
});
// 通过 Symbol 访问
catcher.updateHandler(LOGGER_SYMBOL, newHandler);
catcher.removeHandler(LOGGER_SYMBOL);API 参考
createExceptionCatcher
工厂函数,创建配置好的异常捕获器。现在与构造函数使用相同的配置参数。
createExceptionCatcher(config?: ExceptionCatcherOptions): ExceptionCatcherExceptionCatcher 构造函数
直接实例化异常捕获器类,支持与工厂函数相同的配置参数。
new ExceptionCatcher(options?: ExceptionCatcherOptions)实例方法
| 实例方法名 | 说明 |
| ---------------------------------------- | ------------------------ |
| start() | 启动标准异常监听 |
| stop() | 停止标准异常监听 |
| captureException(error, options?) | 手动捕获异常 |
| setHandlers(handlers) | 设置处理器数组 |
| addHandler(handler) | 添加单个处理器 |
| removeHandler(name) | 移除处理器 |
| updateHandler(name, handler) | 更新处理器 |
| setLeadingHook(hook) | 设置前置钩子 |
| setTrailingHook(hook) | 设置后置钩子 |
| destroy() | 销毁实例 |
类型系统
核心类型
// 处理器名称:支持字符串和 Symbol
type HandlerName = string | symbol;
// 异常处理上下文
type HandlerContext = {
error: Error; // 错误对象
source: string; // 异常来源
processedBy: ProcessRecord[]; // 处理记录
originalEvent?: ErrorEvent | PromiseRejectionEvent; // 原始事件
leadingResult?: LeadingResult; // 前置钩子结果
metadata?: Record<string, unknown>; // 自定义元数据
};
// 异常处理器
type ExceptionHandler = {
name?: HandlerName; // 处理器名称
condition: (context: HandlerContext) => boolean | Promise<boolean>; // 处理条件
handler: (context: HandlerContext) => Promise<void>; // 处理函数
acceptProcessed?: boolean; // 是否接收已处理的异常
mode?: 'serial' | 'parallel'; // 执行模式
};
// 前置钩子
type LeadingHook = {
handler: (context: HandlerContext) => Promise<LeadingResult>;
breakOnError?: boolean; // 出错时是否中断处理链,默认 false 不中断
};
// 后置钩子
type TrailingHook = {
handler: (context: HandlerContext, leadingResult?: LeadingResult) => Promise<void>;
};
// 异常捕获器配置选项
type ExceptionCatcherOptions = {
enableStandardCapture?: boolean; // 控制是否自动监听全局 `error` 和 `unhandledrejection` 事件,默认 true
enableConsoleError?: boolean; // 控制是否输出库内部的错误日志,默认 true
handlers?: ExceptionHandler[]; // 初始异常处理器数组
leadingHook?: LeadingHook; // 初始前置钩子
trailingHook?: TrailingHook; // 初始后置钩子
};许可证
MIT
