# unerror **Repository Path**: jl15988/unerror ## Basic Information - **Project Name**: unerror - **Description**: 统一错误处理库,为 JavaScript 和 TypeScript 项目提供一致的错误管理机制 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-11-28 - **Last Updated**: 2025-11-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # unerror > 统一错误处理库,为 JavaScript 和 TypeScript 项目提供一致的错误管理机制 [![npm version](https://img.shields.io/npm/v/unerror.svg)](https://www.npmjs.com/package/unerror) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ## 特性 - 🎯 **类型安全** - 完整的 TypeScript 类型支持 - 🔗 **错误链追踪** - 追踪错误的因果关系 - 📦 **可序列化** - 支持 JSON 序列化和反序列化 - 🎨 **格式化输出** - 人类可读的错误描述 - 🔧 **简洁 API** - 简单易用的接口设计 - 🌐 **跨平台** - 支持 Node.js 和浏览器 - 📝 **完整注释** - 详细的 JSDoc 文档 ## 安装 ```bash npm install unerror ``` ```bash yarn add unerror ``` ```bash pnpm add unerror ``` ## 快速开始 ### 基本用法 ```typescript import { UnError } from 'unerror'; // 创建简单错误 const error = new UnError('User not found'); // 带因果错误 try { // 某些数据库操作 throw new Error('Connection timeout'); } catch (err) { throw new UnError('Failed to fetch user', err); } ``` ### 错误链 ```typescript // 构建错误链 const dbError = new Error('Connection failed'); const serviceError = new UnError('Database query failed', dbError); const apiError = new UnError('API request failed', serviceError); // 获取完整错误链 const chain = apiError.getErrorChain(); console.log(`Error chain depth: ${chain.length}`); // 3 // 遍历错误链 chain.forEach((err, index) => { console.log(`[${index}] ${err.message}`); }); ``` ### 序列化和反序列化 ```typescript // 序列化错误 const error = new UnError('Operation failed'); const json = JSON.stringify(error.toJSON()); // 通过网络传输或存储到文件... // 反序列化 const data = JSON.parse(json); const restored = UnError.fromJSON(data); console.log(restored.message); // 'Operation failed' console.log(restored.timestamp); // 原始时间戳 ``` ### 格式化输出 ```typescript const error = new UnError('User not found'); // 基本格式化 console.log(error.format()); // 输出: // UnError: User not found // Stack: // at ... // 自定义格式选项 console.log(error.format({ includeStack: true, includeCause: true, indent: 4 })); // 格式化整个错误链 const cause = new Error('Database error'); const error2 = new UnError('Query failed', cause); console.log(error2.formatChain()); // 输出: // UnError: Query failed // Stack: // at ... // ↳ Error: Database error // Stack: // at ... ``` ## API 文档 ### UnError 类 #### 构造函数 ```typescript new UnError(message?: string, cause?: Error | UnError, captureStackTrace?: boolean) ``` **参数:** - `message` - 错误消息(可选) - `cause` - 因果错误,用于构建错误链(可选) - `captureStackTrace` - 是否捕获堆栈跟踪(默认 true) **示例:** ```typescript // 简单错误 const error1 = new UnError('Something went wrong'); // 带因果错误 const error2 = new UnError('Operation failed', originalError); // 禁用堆栈捕获 const error3 = new UnError('Error', undefined, false); ``` #### 属性 - `message: string` - 错误消息 - `name: string` - 错误名称(默认 'UnError') - `cause?: Error | UnError` - 因果错误 - `timestamp: number` - 创建时间戳(毫秒) - `stack?: string` - 堆栈跟踪 #### 实例方法 ##### `toJSON(): SerializedError` 将错误序列化为 JSON 兼容对象。 ```typescript const serialized = error.toJSON(); const json = JSON.stringify(serialized); ``` ##### `getErrorChain(): Array` 获取完整的错误链,从当前错误到根本原因。 ```typescript const chain = error.getErrorChain(); chain.forEach((err, index) => { console.log(`${index}: ${err.message}`); }); ``` ##### `format(options?: FormatOptions): string` 格式化错误为人类可读的字符串。 ```typescript const formatted = error.format({ includeStack: true, includeCause: true, indent: 2 }); console.log(formatted); // 使用堆栈清理 const cleanFormatted = error.format({ includeStack: true, cleanStack: { removeNodeInternals: true, removeNodeModules: true } }); console.log(cleanFormatted); ``` **FormatOptions:** - `includeStack?: boolean` - 是否包含堆栈跟踪(默认 true) - `includeCause?: boolean` - 是否包含因果错误(默认 true) - `indent?: number` - 缩进空格数(默认 2) - `colors?: boolean` - 是否使用颜色(默认 false) - `cleanStack?: CleanStackOptions` - 堆栈清理选项(可选) - `removeNodeInternals?: boolean` - 移除 Node.js 内部模块 - `removeNodeModules?: boolean` - 移除 node_modules 帧 - `removeAnonymous?: boolean` - 移除匿名函数帧 ##### `formatChain(options?: FormatOptions): string` 格式化整个错误链为字符串。 ```typescript const formatted = error.formatChain({ includeStack: false, indent: 2 }); console.log(formatted); // 使用堆栈清理 const cleanFormatted = error.formatChain({ includeStack: true, cleanStack: { removeNodeInternals: true, removeNodeModules: true, removeAnonymous: false } }); console.log(cleanFormatted); ``` ##### `withCause(cause: Error | UnError): UnError` 创建一个新的错误实例,包含指定的因果错误。 ```typescript const error = new UnError('Operation failed'); const wrapped = error.withCause(originalError); ``` ##### `clone(): UnError` 克隆当前错误实例。 ```typescript const error = new UnError('Test error'); const cloned = error.clone(); ``` ##### `parseStack(): StackFrame[]` 解析堆栈跟踪为结构化的堆栈帧数组。 ```typescript const frames = error.parseStack(); frames.forEach(frame => { console.log(`${frame.functionName} at ${frame.fileName}:${frame.lineNumber}`); }); ``` **StackFrame 接口:** ```typescript interface StackFrame { functionName?: string; fileName?: string; lineNumber?: number; columnNumber?: number; raw: string; } ``` ##### `print(options?: FormatOptions): this` 快速打印错误栈到控制台,用于调试。 **注意:** UnError 实例也可以直接通过 `console.log()`、`console.error()` 等方法打印,会自动调用 `toString()` 方法显示错误信息。 ```typescript // 基本用法 const error = new UnError('Operation failed', cause); error.print(); // 自定义选项 error.print({ includeStack: false }); // 链式调用 throw new UnError('Failed').print(); // 也可以直接使用 console 方法 console.error(error); // 自动显示错误信息 ``` #### 静态方法 ##### `UnError.fromJSON(data: SerializedError): UnError` 从序列化数据创建错误实例。 ```typescript const data = JSON.parse(json); const error = UnError.fromJSON(data); ``` ##### `UnError.isUnError(error: unknown): error is UnError` 类型守卫,检查值是否为 UnError 实例。 ```typescript if (UnError.isUnError(error)) { console.log('This is an UnError instance'); console.log(error.timestamp); } ``` ## 使用场景 ### 1. API 错误处理 ```typescript import { UnError } from 'unerror'; async function fetchUser(userId: string) { try { const response = await fetch(`/api/users/${userId}`); if (!response.ok) { throw new UnError(`Failed to fetch user: ${response.statusText}`); } return await response.json(); } catch (err) { throw new UnError('User fetch operation failed', err as Error); } } // 使用 try { const user = await fetchUser('123'); } catch (err) { if (UnError.isUnError(err)) { console.error(err.formatChain()); } } ``` ### 2. 分布式系统错误传递 ```typescript // 服务 A const error = new UnError('Database query failed'); // 序列化并通过网络发送 const json = JSON.stringify(error.toJSON()); await sendToServiceB(json); // 服务 B const data = JSON.parse(receivedJson); const error = UnError.fromJSON(data); // 添加更多上下文 throw new UnError('Service A operation failed', error); ``` ### 3. 日志记录 ```typescript import { UnError } from 'unerror'; try { // 某些操作 throw new Error('Something went wrong'); } catch (err) { const error = new UnError('Operation failed', err as Error); // 记录格式化的错误链 logger.error(error.formatChain({ includeStack: true })); // 或记录 JSON 格式 logger.error(JSON.stringify(error.toJSON(), null, 2)); } ``` ### 4. 错误链分析 ```typescript function analyzeError(error: Error | UnError) { if (!UnError.isUnError(error)) { console.log('Standard error:', error.message); return; } const chain = error.getErrorChain(); console.log(`Error chain depth: ${chain.length}`); // 查找特定类型的错误 const dbError = chain.find(err => err.message.includes('database') || err.message.includes('connection') ); if (dbError) { console.log('Found database error:', dbError.message); } // 解析堆栈 const frames = error.parseStack(); if (frames.length > 0) { const topFrame = frames[0]; console.log(`Error occurred at: ${topFrame.fileName}:${topFrame.lineNumber}`); } } ``` ### 5. 快速调试 ```typescript import { UnError } from 'unerror'; function processData(data: any) { try { // 某些处理逻辑 if (!data.id) { throw new UnError('Invalid data: missing id').print(); } // 更多处理... } catch (err) { // 快速打印错误链进行调试 if (UnError.isUnError(err)) { err.print({ includeStack: true }); } throw err; } } // 开发环境中快速查看错误 const error = new UnError('Database connection failed', originalError); error.print(); // 立即打印到控制台 // 也支持直接通过 console 方法打印 console.log(error); // 自动调用 toString() console.error(error); // 推荐用于错误输出 console.dir(error); // 查看对象结构 ``` ## TypeScript 支持 unerror 使用 TypeScript 编写,提供完整的类型定义: ```typescript import type { UnError, SerializedError, FormatOptions, StackFrame } from 'unerror'; // 类型安全的错误处理 function handleError(error: unknown): void { if (UnError.isUnError(error)) { // TypeScript 知道这里 error 是 UnError 类型 console.log(error.timestamp); console.log(error.formatChain()); } } ``` ## 工厂函数 库还提供了工厂函数用于快速创建错误(需要从 factory 模块导入): ```typescript import { createError, createErrorClass } from 'unerror'; // 快速创建错误 const error = createError('Operation failed'); // 创建自定义错误类 const DatabaseError = createErrorClass('DatabaseError'); const dbError = new DatabaseError('Connection failed'); console.log(dbError.name); // 'DatabaseError' ``` ## 兼容性 - **Node.js**: >= 16.0.0 - **TypeScript**: >= 4.5.0 - **浏览器**: 支持 ES2020 的现代浏览器 - **模块系统**: ESM 和 CommonJS ## 运行示例 项目包含了多个可运行的示例,展示各种使用场景: ```bash # 运行所有示例 npm run examples # 运行单个示例 npm run example examples/01-basic-usage.ts npm run example examples/02-error-chain.ts npm run example examples/03-serialization.ts npm run example examples/04-formatting.ts npm run example examples/05-stack-parsing.ts npm run example examples/06-real-world.ts npm run example examples/07-custom-error-classes.ts npm run example examples/08-print-method.ts ``` 示例包括: - **01-basic-usage.ts** - 基本用法 - **02-error-chain.ts** - 错误链操作 - **03-serialization.ts** - 序列化和反序列化 - **04-formatting.ts** - 格式化输出 - **05-stack-parsing.ts** - 堆栈跟踪解析 - **06-real-world.ts** - 真实场景应用 - **07-custom-error-classes.ts** - 自定义错误类 - **08-print-method.ts** - 打印错误栈 查看 [examples/README.md](./examples/README.md) 了解更多详情。 ## 许可证 MIT ## 贡献 欢迎贡献!请随时提交 issue 或 pull request。