Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Handle errors in a simple, stable, consistent way

License

NotificationsYou must be signed in to change notification settings

ehmicky/modern-errors

modern-errors logo

NodeBrowsersTypeScriptCodecovMinified sizeMastodonMedium

Handle errors in a simple, stable, consistent way.

Features

Simple patterns to:

Stability:

Plugins

Example

Create errorclasses.

importModernErrorfrom'modern-errors'exportconstBaseError=ModernError.subclass('BaseError')exportconstUnknownError=BaseError.subclass('UnknownError')exportconstInputError=BaseError.subclass('InputError')exportconstAuthError=BaseError.subclass('AuthError')exportconstDatabaseError=BaseError.subclass('DatabaseError')

Set errorproperties.

thrownewInputError('Invalid file path',{props:{filePath:'/...'}})

Wrap errors.

try{// ...}catch(cause){thrownewInputError('Could not read the file.',{ cause})}

Normalize errors.

try{throw'Missing file path.'}catch(error){// Normalized from a string to a `BaseError` instancethrowBaseError.normalize(error)}

Useplugins.

importModernErrorfrom'modern-errors'importmodernErrorsSerializefrom'modern-errors-serialize'exportconstBaseError=ModernError.subclass('BaseError',{plugins:[modernErrorsSerialize],})// ...// Serialize error as JSON, then back to identical error instanceconsterror=newInputError('Missing file path.')consterrorString=JSON.stringify(error)constidenticalError=BaseError.parse(JSON.parse(errorString))

Install

npm install modern-errors

If anyplugin is used, it must also be installed.

npm install modern-errors-{pluginName}

This package works in both Node.js >=18.18.0 andbrowsers.

This is an ES module. It must be loaded usinganimport orimport() statement,notrequire(). If TypeScript is used, it must be configured tooutput ES modules,not CommonJS.

Usage

⛑️ Error classes

Create error classes

importModernErrorfrom'modern-errors'exportconstBaseError=ModernError.subclass('BaseError')exportconstUnknownError=BaseError.subclass('UnknownError')exportconstInputError=BaseError.subclass('InputError')exportconstAuthError=BaseError.subclass('AuthError')exportconstDatabaseError=BaseError.subclass('DatabaseError')

Export error classes

Exporting and documenting all error classes allows consumers to check them. Thisalso enables sharing error classes between modules.

Check error classes

if(errorinstanceofInputError){// ...}

Error subclasses

ErrorClass.subclass() returns asubclass.Parent classes'options are merged with their subclasses.

exportconstBaseError=ModernError.subclass('BaseError',{props:{isError:true},})exportconstInputError=BaseError.subclass('InputError',{props:{isUserError:true},})consterror=newInputError('...')console.log(error.isError)// trueconsole.log(error.isUserError)// trueconsole.log(errorinstanceofBaseError)// trueconsole.log(errorinstanceofInputError)// true

🏷️ Error properties

Error class properties

constInputError=BaseError.subclass('InputError',{props:{isUserError:true},})consterror=newInputError('...')console.log(error.isUserError)// true

Error instance properties

consterror=newInputError('...',{props:{isUserError:true}})console.log(error.isUserError)// true

Internal error properties

Error properties that are internal or secret can be prefixed with_. Thismakes themnon-enumerable,which prevents iterating or logging them.

consterror=newInputError('...',{props:{userId:6,_isUserError:true},})console.log(error.userId)// 6console.log(error._isUserError)// trueconsole.log(Object.keys(error))// ['userId']console.log(error)// `userId` is logged, but not `_isUserError`

🎀 Wrap errors

Throw errors

thrownewInputError('Missing file path.')

Wrap inner error

Any error'smessage,class andoptions can be wrapped using thestandardcause option.

Instead of being set as acause property, the inner error is directlymerged to the outer error,including itsmessage,stack,name,AggregateError.errorsand anyadditional property.

try{// ...}catch(cause){thrownewInputError('Could not read the file.',{ cause})}

Wrap error message

The outer error message is appended, unless it is empty. If the outer errormessage ends with: or:\n, it is prepended instead.

constcause=newInputError('File does not exist.')// InputError: File does not exist.thrownewInputError('',{ cause})
// InputError: File does not exist.// Could not read the file.thrownewInputError('Could not read the file.',{ cause})
// InputError: Could not read the file: File does not exist.thrownewInputError(`Could not read the file:`,{ cause})
// InputError: Could not read the file:// File does not exist.thrownewInputError(`Could not read the file:\n`,{ cause})

Wrap error class

The outer error's class replaces the inner one.

try{thrownewAuthError('...')}catch(cause){// Now an InputErrorthrownewInputError('...',{ cause})}

Except when the outer error's class is a parent class, such asBaseError.

try{thrownewAuthError('...')}catch(cause){// Still an AuthErrorthrownewBaseError('...',{ cause})}

Wrap error options

The outer error'sprops andplugin options are merged.

try{thrownewAuthError('...',innerOptions)}catch(cause){// `outerOptions` are merged with `innerOptions`thrownewBaseError('...',{ ...outerOptions, cause})}

Aggregate errors

Theerrors option aggregates multiple errors into one. Thisis likenew AggregateError(errors)except that it works with any error class.

constdatabaseError=newDatabaseError('...')constauthError=newAuthError('...')thrownewInputError('...',{errors:[databaseError,authError]})// InputError: ... {//   [errors]: [//     DatabaseError: ...//     AuthError: ...//   ]// }

🚨 Normalize errors

Wrapped errors

Any error can be directly passed to thecause orerrors option, even if it isinvalid,unknown or notnormalized.

try{// ...}catch(cause){thrownewInputError('...',{ cause})}

Invalid errors

Manipulating errors that are notError instancesor that haveinvalid propertiescan lead to unexpected bugs.BaseError.normalize() fixes that.

try{throw'Missing file path.'}catch(invalidError){// This fails: `invalidError.message` is `undefined`console.log(invalidError.message.trim())}
try{throw'Missing file path.'}catch(invalidError){constnormalizedError=BaseError.normalize(invalidError)// This works: 'Missing file path.'// `normalizedError` is a `BaseError` instance.console.log(normalizedError.message.trim())}

🐞 Unknown errors

Handling known errors

Known errors should be handled in atry {} catch {} block andwrapped with aspecific class.That block should only cover the statement that might throw in order to preventcatching other unrelated errors.

try{returnregExp.test(value)}catch(error){// Now an `InputError` instancethrownewInputError('Invalid regular expression:',{cause:error})}

Normalizing unknown errors

If an error is not handled as describedabove, it isconsideredunknown. This indicates an unexpected exception, usually a bug.BaseError.normalize(error, UnknownError)assigns theUnknownError class to those errors.

exportconstUnknownError=BaseError.subclass('UnknownError')
try{returnregExp.test(value)}catch(error){// Now an `UnknownError` instancethrowBaseError.normalize(error,UnknownError)}

Top-level error handler

Wrapping a module's main functions withBaseError.normalize(error, UnknownError)ensures every error being thrown isvalid, appliesplugins, and has a class that is eitherknown orUnknownError.

exportconstmain=()=>{try{// ...}catch(error){throwBaseError.normalize(error,UnknownError)}}

🔌 Plugins

List of plugins

Plugins extendmodern-errors features. All available plugins arelisted here.

Adding plugins

To use a plugin, please install it, then pass it to theplugins option.

npm install modern-errors-{pluginName}
importModernErrorfrom'modern-errors'importmodernErrorsBugsfrom'modern-errors-bugs'importmodernErrorsSerializefrom'modern-errors-serialize'exportconstBaseError=ModernError.subclass('BaseError',{plugins:[modernErrorsBugs,modernErrorsSerialize],})// ...

Custom plugins

Please see thefollowing documentation to create your ownplugin.

Plugin options

Most plugins can be configured with options. The option's name is the same asthe plugin.

constoptions={// `modern-errors-bugs` optionsbugs:'https://github.com/my-name/my-project/issues',// `props` can be configured and modified like plugin optionsprops:{userId:5},}

Plugin options can apply to (in priority order):

exportconstBaseError=ModernError.subclass('BaseError',options)
exportconstInputError=BaseError.subclass('InputError',options)
thrownewInputError('...',options)
  • A plugin method call: last argument, passing only that plugin's options
ErrorClass[methodName](...args,options[pluginName])
error[methodName](...args,options[pluginName])

🔧 Custom logic

Thecustom option can be used to provide an errorclasswith additional methods,constructor, properties or options.

exportconstInputError=BaseError.subclass('InputError',{// The `class` must extend from the parent error classcustom:classextendsBaseError{// If a `constructor` is defined, its parameters must be (message, options)// Additional `options` can be defined.constructor(message,options){message+=options?.suffix??''super(message,options)}isUserInput(){// ...}},})consterror=newInputError('Wrong user name',{suffix:': example'})console.log(error.message)// 'Wrong user name: example'console.log(error.isUserInput())

🤓 TypeScript

Please see thefollowing documentation for informationabout TypeScript types.

API

ModernError

Top-levelErrorClass.

ErrorClass.subclass(name, options?)

name:string
options:ClassOptions?

Creates and returns a childErrorClass.

options

options.props

Type:object

Error class properties.

options.plugins

Type:Plugin[]

options.custom

Type:class extends ErrorClass {}

Custom class to add any methods,constructor or properties.

options.*

Anyplugin options can also be specified.

new ErrorClass(message, options?)

message:string
options:InstanceOptions?
Return value:Error

options

options.props

Type:object

Error instance properties.

options.cause

Type:any

Inner error beingwrapped.

options.errors

Type:any[]

Array of errors beingaggregated.

options.*

Anyplugin options can also be specified.

ErrorClass.normalize(error, NewErrorClass?)

error:Error | any
NewErrorClass: subclass ofErrorClass
Return value:Error

Normalizesinvalid errors.

Iferror is an instance ofErrorClass (or one of its subclasses), it is leftas is. Otherwise, it isconverted toNewErrorClass, which defaults toErrorClass itself.

Modules

This framework brings together a collection of modules which can also be usedindividually:

Support

For any question,don't hesitate tosubmit an issue on GitHub.

Everyone is welcome regardless of personal background. We enforce aCode of conduct in order to promote a positive andinclusive environment.

Contributing

This project was made with ❤️. The simplest way to give back is by starring andsharing it online.

If the documentation is unclear or has a typo, please click on the page'sEditbutton (pencil icon) and suggest a correction.

If you would like to help us fix a bug or add a new feature, please check ourguidelines. Pull requests are welcome!

ehmicky
ehmicky

💻🎨🤔📖
const_var
const_var

🤔💬
Andy Brenneke
Andy Brenneke

🤔💬🐛
Graham Fisher
Graham Fisher

🐛
renzor
renzor

💬🤔
Eugene
Eugene

💻🐛
Jonathan Chambers
Jonathan Chambers

⚠️🐛
heyhey123
heyhey123

🐛
Benjamin Kroeger
Benjamin Kroeger

🐛

[8]ページ先頭

©2009-2025 Movatter.jp