modern-errors

modern-errors

强大而灵活的JavaScript错误处理库

modern-errors是一个功能丰富的JavaScript错误处理库。它简化了错误类的创建、属性设置、错误包装和聚合等操作,并能有效区分已知和未知错误。该库以稳定性著称,拥有全面的测试覆盖和严格的TypeScript类型支持。通过插件系统,modern-errors还可扩展多种功能,如命令行界面错误处理、进程错误管理和错误序列化等。

错误处理异常封装错误类插件系统TypeScriptGithub开源项目
<picture> <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/ehmicky/design/main/modern-errors/modern-errors_dark.svg"/> <img alt="modern-errors 标志" src="https://yellow-cdn.veclightyear.com/835a84d5/909155bd-6d0c-4b60-b7be-0ebdd82184dd.svg" width="600"/> </picture>

Node 浏览器 TypeScript Codecov 压缩后大小 Mastodon Medium

以简单、稳定、一致的方式处理错误。

招聘我

如果您正在寻找一位 Node.js API 或 CLI 工程师(具有11年经验),请联系我。我最近在 Netlify BuildNetlify Plugins 担任技术主管2.5年。我可以接受全职远程职位。

特性

简单的模式用于:

稳定性:

插件

示例

创建错误

import ModernError from 'modern-errors' export const BaseError = ModernError.subclass('BaseError') export const UnknownError = BaseError.subclass('UnknownError') export const InputError = BaseError.subclass('InputError') export const AuthError = BaseError.subclass('AuthError') export const DatabaseError = BaseError.subclass('DatabaseError')

设置错误属性

throw new InputError('无效的文件路径', { props: { filePath: '/...' } })

包装错误。

try { // ... } catch (cause) { throw new InputError('无法读取文件。', { cause }) }

规范化错误。

try { throw '缺少文件路径。' } catch (error) { // 从字符串规范化为 `BaseError` 实例 throw BaseError.normalize(error) }

使用插件

import ModernError from 'modern-errors' import modernErrorsSerialize from 'modern-errors-serialize' export const BaseError = ModernError.subclass('BaseError', { plugins: [modernErrorsSerialize], }) // ... // 将错误序列化为 JSON,然后再解析回相同的错误实例 const error = new InputError('缺少文件路径。') const errorString = JSON.stringify(error) const identicalError = BaseError.parse(JSON.parse(errorString))

安装

npm install modern-errors

如果使用任何插件,也必须安装它们。

npm install modern-errors-{插件名}

这个包同时适用于 Node.js >=18.18.0 和浏览器

这是一个 ES 模块。它必须使用 import 或 import() 语句加载,而不是 require()。如果使用 TypeScript,必须将其配置为输出 ES 模块,而不是 CommonJS。

使用方法

⛑️ 错误类

创建错误类

import ModernError from 'modern-errors' export const BaseError = ModernError.subclass('BaseError') export const UnknownError = BaseError.subclass('UnknownError') export const InputError = BaseError.subclass('InputError') export const AuthError = BaseError.subclass('AuthError') export const DatabaseError = BaseError.subclass('DatabaseError')

导出错误类

导出并记录所有错误类允许使用者对其进行检查。这也使得在模块之间共享错误类成为可能。

检查错误类

if (error instanceof InputError) { // ... }

错误子类

ErrorClass.subclass()返回一个子类。 父类的选项与其子类的选项合并。

export const BaseError = ModernError.subclass('BaseError', { props: { isError: true }, }) export const InputError = BaseError.subclass('InputError', { props: { isUserError: true }, }) const error = new InputError('...') console.log(error.isError) // true console.log(error.isUserError) // true console.log(error instanceof BaseError) // true console.log(error instanceof InputError) // true

🏷️ 错误属性

错误类属性

const InputError = BaseError.subclass('InputError', { props: { isUserError: true }, }) const error = new InputError('...') console.log(error.isUserError) // true

错误实例属性

const error = new InputError('...', { props: { isUserError: true } }) console.log(error.isUserError) // true

内部错误属性

内部或秘密的错误属性可以用_作为前缀。这使它们成为不可枚举的,从而防止被迭代或记录。

const error = new InputError('...', { props: { userId: 6, _isUserError: true }, }) console.log(error.userId) // 6 console.log(error._isUserError) // true console.log(Object.keys(error)) // ['userId'] console.log(error) // 记录`userId`,但不记录`_isUserError`

🎀 包装错误

抛出错误

throw new InputError('缺少文件路径。')

包装内部错误

任何错误的消息选项都可以使用标准cause选项进行包装。

内部错误不会被设置为cause属性,而是直接合并到外部错误中,包括其messagestacknameAggregateError.errors和任何附加属性

try { // ... } catch (cause) { throw new InputError('无法读取文件。', { cause }) }

包装错误消息

外部错误消息会被追加,除非它为空。如果外部错误消息以::\n结尾,则会被前置。

const cause = new InputError('文件不存在。') // InputError: 文件不存在。 throw new InputError('', { cause })
// InputError: 文件不存在。 // 无法读取文件。 throw new InputError('无法读取文件。', { cause })
// InputError: 无法读取文件:文件不存在。 throw new InputError(`无法读取文件:`, { cause })
// InputError: 无法读取文件: // 文件不存在。 throw new InputError(`无法读取文件:\n`, { cause })

包装错误类

外部错误的类会替换内部错误的类。

try { throw new AuthError('...') } catch (cause) { // 现在是InputError throw new InputError('...', { cause }) }

除非外部错误的类是父类,比如BaseError

try { throw new AuthError('...') } catch (cause) { // 仍然是AuthError throw new BaseError('...', { cause }) }

包装错误选项

外部错误的props插件选项会被合并。

try { throw new AuthError('...', innerOptions) } catch (cause) { // `outerOptions`与`innerOptions`合并 throw new BaseError('...', { ...outerOptions, cause }) }

聚合错误

errors选项将多个错误聚合成一个。这类似于new AggregateError(errors),但适用于任何错误类。

const databaseError = new DatabaseError('...') const authError = new AuthError('...') throw new InputError('...', { errors: [databaseError, authError] }) // InputError: ... { // [errors]: [ // DatabaseError: ... // AuthError: ... // ] // }

🚨 规范化错误

包装的错误

任何错误都可以直接传递给causeerrors选项,即使它是无效的未知的或未规范化的

try { // ... } catch (cause) { throw new InputError('...', { cause }) }

无效错误

操作不是Error实例或具有无效属性的错误可能导致意外的错误。 BaseError.normalize()可以解决这个问题。

try { throw '缺少文件路径。' } catch (invalidError) { // 这会失败:`invalidError.message`是`undefined` console.log(invalidError.message.trim()) }
try { throw '缺少文件路径。' } catch (invalidError) { const normalizedError = BaseError.normalize(invalidError) // 这样可以正常工作: '缺少文件路径。' // `normalizedError` 是 `BaseError` 的实例。 console.log(normalizedError.message.trim()) }

🐞 未知错误

处理已知错误

已知错误应该在 try {} catch {} 块中处理,并用特定类包装。该块应该只覆盖可能抛出错误的语句,以防止捕获其他不相关的错误。

try { return regExp.test(value) } catch (error) { // 现在是 `InputError` 实例 throw new InputError('无效的正则表达式:', { cause: error }) }

标准化未知错误

如果错误没有按照上述方式处理,就被视为_未知_。这表示发生了意外异常,通常是一个bug。 BaseError.normalize(error, UnknownError)UnknownError 类分配给这些错误。

export const UnknownError = BaseError.subclass('UnknownError')
try { return regExp.test(value) } catch (error) { // 现在是 `UnknownError` 实例 throw BaseError.normalize(error, UnknownError) }

顶级错误处理器

BaseError.normalize(error, UnknownError)包装模块的主要函数可以确保每个抛出的错误都是有效的,应用了插件,并且具有已知UnknownError类。

export const main = () => { try { // ... } catch (error) { throw BaseError.normalize(error, UnknownError) } }

🔌 插件

插件列表

插件扩展了 modern-errors 的功能。所有可用的插件都列在这里

添加插件

要使用插件,请先安装它,然后将其传递给plugins 选项

npm install modern-errors-{pluginName}
import ModernError from 'modern-errors' import modernErrorsBugs from 'modern-errors-bugs' import modernErrorsSerialize from 'modern-errors-serialize' export const BaseError = ModernError.subclass('BaseError', { plugins: [modernErrorsBugs, modernErrorsSerialize], }) // ...

自定义插件

请查看以下文档以创建你自己的插件。

插件选项

大多数插件可以通过选项进行配置。选项的名称与插件相同。

const options = { // `modern-errors-bugs` 选项 bugs: 'https://github.com/my-name/my-project/issues', // `props` 可以像插件选项一样配置和修改 props: { userId: 5 }, }

插件选项可以应用于(按优先顺序):

export const BaseError = ModernError.subclass('BaseError', options)
export const InputError = BaseError.subclass('InputError', options)
throw new InputError('...', options)
  • 插件方法调用: 最后一个参数,仅传递该插件的选项
ErrorClass[methodName](...args, options[pluginName])
error[methodName](...args, options[pluginName])

🔧 自定义逻辑

custom 选项可用于为错误提供额外的方法、constructor、属性或选项。

export const InputError = BaseError.subclass('InputError', { // `class` 必须继承自父错误类 custom: class extends BaseError { // 如果定义了 `constructor`,其参数必须是 (message, options) // 可以定义额外的 `options`。 constructor(message, options) { message += options?.suffix ?? '' super(message, options) } isUserInput() { // ... } }, }) const error = new InputError('错误的用户名', { suffix: ': 示例' }) console.log(error.message) // '错误的用户名: 示例' console.log(error.isUserInput())

🤓 TypeScript

请查看以下文档了解有关 TypeScript 类型的信息。

API

ModernError

顶级 ErrorClass

ErrorClass.subclass(name, options?)

name: string
options: ClassOptions?

创建并返回一个子 ErrorClass

options

options.props

类型: object

错误类属性

options.plugins

类型: Plugin[]

options.custom

类型: class extends ErrorClass {}

自定义类,用于添加任何方法、constructor 或属性。

options.*

任何插件选项也可以在此指定。

new ErrorClass(message, options?)

message: string
options: InstanceOptions?
返回值: Error

options

options.props

类型: object

错误实例属性

options.cause

类型: any

包装的内部错误。

options.errors

类型: any[]

聚合的错误数组。

options.*

任何插件选项也可以在此指定。

ErrorClass.normalize(error, NewErrorClass?)

error: Error | any
NewErrorClass: ErrorClass 的子类
返回值: Error

标准化无效错误

如果 error 的类是 ErrorClass 的子类,它将保持不变。 否则,它将被转换为 NewErrorClass,默认为 ErrorClass 本身。

模块

这个框架汇集了一系列可以单独使用的模块:

支持

如有任何问题,请_不要犹豫_在 GitHub 上提交问题

我们欢迎所有人,不论个人背景如何。我们执行行为准则以促进积极和包容的环境。

贡献

这个项目是用 ❤️ 制作的。回馈的最简单方式是给它加星并在网上分享。

如果文档不清楚或有错别字,请点击页面的编辑按钮(铅笔图标)并提出修改建议。

如果您想帮助我们修复错误或添加新功能,请查看我们的指南。欢迎提交拉取请求!

<!-- 感谢我们出色的贡献者: --> <!-- ALL-CONTRIBUTORS-LIST:START --> <!-- prettier-ignore-start --> <!-- markdownlint-disable --> <table> <tbody> <tr> <td align="center" valign="top" width="14.28%"><a href="https://fosstodon.org/@ehmicky"><img src="https://avatars2.githubusercontent.com/u/8136211?v=4?s=100" width="100px;" alt="ehmicky"/><br /><sub><b>ehmicky</b></sub></a><br /><a href="https://github.com/ehmicky/modern-errors/commits?author=ehmicky" title="代码">💻</a> <a href="#design-ehmicky" title="设计">🎨</a> <a href="#ideas-ehmicky" title="想法、规划与反馈">🤔</a> <a href="https://github.com/ehmicky/modern-errors/commits?author=ehmicky" title="文档">📖</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/bhvngt"><img src="https://avatars.githubusercontent.com/u/79074469?v=4?s=100" width="100px;" alt="const_var"/><br /><sub><b>const_var</b></sub></a><br /><a href="#ideas-bhvngt" title="想法、规划与反馈">🤔</a> <a href="#question-bhvngt" title="回答问题">💬</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/abrenneke"><img src="https://avatars.githubusercontent.com/u/342540?v=4?s=100" width="100px;" alt="Andy Brenneke"/><br /><sub><b>Andy Brenneke</b></sub></a><br /><a href="#ideas-abrenneke" title="想法、规划与反馈">🤔</a> <a href="#question-abrenneke" title="回答问题">💬</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/tgfisher4"><img src="https://avatars.githubusercontent.com/u/49082176?v=4?s=100" width="100px;" alt="Graham Fisher"/><br /><sub><b>Graham Fisher</b></sub></a><br /><a href="https://github.com/ehmicky/modern-errors/issues?q=author%3Atgfisher4" title="错误报告">🐛</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/renzor-fist"><img src="https://avatars.githubusercontent.com/u/117486829?v=4?s=100" width="100px;" alt="renzor"/><br /><sub><b>renzor</b></sub></a><br /><a href="#question-renzor-fist" title="回答问题">💬</a> <a href="#ideas-renzor-fist" title="想法、规划与反馈">🤔</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/eugene1g"><img src="https://avatars.githubusercontent.com/u/147496?v=4?s=100" width="100px;" alt="Eugene"/><br /><sub><b>Eugene</b></sub></a><br /><a href="https://github.com/ehmicky/modern-errors/commits?author=eugene1g" title="代码">💻</a> <a href="https://github.com/ehmicky/modern-errors/issues?q=author%3Aeugene1g" title="错误报告">🐛</a></td> <td align="center" valign="top" width="14.28%"><a href="http://uk.linkedin.com/in/jonathanmarkchambers/"><img src="https://avatars.githubusercontent.com/u/49592?v=4?s=100" width="100px;" alt="Jonathan Chambers"/><br /><sub><b>Jonathan Chambers</b></sub></a><br /><a href="https://github.com/ehmicky/modern-errors/commits?author=jmchambers" title="测试">⚠️</a> <a href="https://github.com/ehmicky/modern-errors/issues?q=author%3Ajmchambers" title="错误报告">🐛</a></td> </tr> </tbody> </table> <!-- markdownlint-restore --> <!-- prettier-ignore-end --> <!-- ALL-CONTRIBUTORS-LIST:END -->

编辑推荐精选

Trae

Trae

字节跳动发布的AI编程神器IDE

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
问小白

问小白

全能AI智能助手,随时解答生活与工作的多样问题

问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。

热门AI助手AI对话AI工具聊天机器人
Transly

Transly

实时语音翻译/同声传译工具

Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

AI办公办公工具AI工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图热门
讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

热门AI开发模型训练AI工具讯飞星火大模型智能问答内容创作多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

咔片PPT

咔片PPT

AI助力,做PPT更简单!

咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。

讯飞绘文

讯飞绘文

选题、配图、成文,一站式创作,让内容运营更高效

讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。

热门AI辅助写作AI工具讯飞绘文内容运营AI创作个性化文章多平台分发AI助手
材料星

材料星

专业的AI公文写作平台,公文写作神器

AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。

openai-agents-python

openai-agents-python

OpenAI Agents SDK,助力开发者便捷使用 OpenAI 相关功能。

openai-agents-python 是 OpenAI 推出的一款强大 Python SDK,它为开发者提供了与 OpenAI 模型交互的高效工具,支持工具调用、结果处理、追踪等功能,涵盖多种应用场景,如研究助手、财务研究等,能显著提升开发效率,让开发者更轻松地利用 OpenAI 的技术优势。

下拉加载更多