CodecovBuildNodeTwitterMedium

Handle errors like it’s 2022.

Example

Create the error types and error handler.

// `error.js`import modernErrors from 'modern-errors'export const { errorHandler, InputError, AuthError, DatabaseError } =  modernErrors()

Wrap each main function with the error handler.

import { errorHandler } from './error.js'export const main = async function (filePath) {  try {    return await readContents(filePath)  } catch (error) {    throw errorHandler(error)  }}

Throw/rethrow errors.

import { InputError } from './error.js'const readContents = async function (filePath) {  try {    return await readFile(filePath)  } catch (cause) {    throw new InputError(`Could not read ${filePath}`, { cause })  }}

Install

npm install modern-errors

This package is an ES module and must be loaded usingan import or import() statement,not require().

API

modernErrors(options?)

options objectReturn value: object

Options

bugsUrl

Type: string | URL

onCreate

Type: (error, params) => void

This is called on new ErrorType('message', params).

By default, it sets any params as error properties. However, you can overrideit with any custom logic to validate, normalize params, etc.

Return value

errorHandler

Type: (anyException) => Error

Any error type

Type: ErrorType

Usage

Creating error types and handler

// error.jsimport modernErrors from 'modern-errors'export const { errorHandler, InputError, AuthError, DatabaseError } =  modernErrors()

Error handler

Each main function should be wrapped with the error handler.

import { errorHandler } from './error.js'export const main = async function (filePath) {  try {    return await readContents(filePath)  } catch (error) {    throw errorHandler(error)  }}

Throwing errors

import { InputError } from './error.js'const validateFilePath = function (filePath) {  if (filePath === '') {    throw new InputError('Missing file path')  }}

Invalid errors

Exceptions that are an Error instance or have invalid/missing error propertiesare normalized byerrorHandler.

import { InputError, errorHandler } from './error.js'export const main = function (filePath) {  try {    throw 'message'  } catch (error) {    throw errorHandler(error) // Normalized to an `Error` instance  }}

Wrapping error message

import { InputError } from './error.js'const readContents = async function (filePath) {  try {    return await readFile(filePath)  } catch (cause) {    throw new InputError(`Could not read ${filePath}`, { cause })    // InputError: File does not exist.    // Could not read /example/path  }}

If the parent error message ends with :, that message is prepended instead.

throw new InputError(`Could not read ${filePath}:`, { cause })// InputError: Could not read /example/path: File does not exist.

: can optionally be followed a newline.

throw new InputError(`Could not read ${filePath}:\n`, { cause })// InputError: Could not read /example/path:// File does not exist.

Catching errors

The errorHandlermerges all error cause sothere is no need totraverse error.cause.All properties are merged:message,stack,nameAggregateError.errorsand any additional property. Thefinal stack traceis simple yet keeps all information.

import { InputError, errorHandler } from './error.js'export const exampleLibrary = async function (filePath) {  try {    return await readContents(filePath)  } catch (error) {    throw errorHandler(error)  }}const readContents = async function (filePath) {  try {    return await readFile(filePath)  } catch (cause) {    throw new InputError(`Could not read ${filePath}`, { cause })  }}
import exampleLibrary from 'example-library'const callLib = async function (filePath) {  try {    return await exampleLibrary(filePath)  } catch (error) {    // No need to look for `error.cause`.    // All `error.cause` have already been merged by `example-library`.    console.log(error)  }}

Support

For any question, don’t hesitate to submit 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’s Editbutton (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!

GitHub

View Github