UNPKG

9.4 kBMarkdownView Raw
1# Typescript Custom Error
2
3[![NPM version](https://img.shields.io/npm/v/ts-custom-error.svg?colorB=green)](https://www.npmjs.com/package/ts-custom-error)
4[![Pet project](https://img.shields.io/badge/maintain-pet_project-yellow.svg?logo=github)](#automate-all-the-things)
5[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
6[![Build Status](https://img.shields.io/travis/adriengibrat/ts-custom-error.svg)](https://travis-ci.org/adriengibrat/ts-custom-error)
7[![BCH compliance](https://bettercodehub.com/edge/badge/adriengibrat/ts-custom-error?branch=master)](https://bettercodehub.com/results/adriengibrat/ts-custom-error)
8[![Maintainability](https://api.codeclimate.com/v1/badges/eb4eb956bc028c49f7aa/maintainability)](https://codeclimate.com/github/adriengibrat/ts-custom-error/maintainability)
9[![Test Coverage](https://api.codeclimate.com/v1/badges/eb4eb956bc028c49f7aa/test_coverage)](https://codeclimate.com/github/adriengibrat/ts-custom-error/test_coverage)
10[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
11[![Install size](https://badgen.net/packagephobia/install/ts-custom-error)](https://packagephobia.now.sh/result?p=ts-custom-error)
12[![Bundle size](https://badgen.net/bundlephobia/minzip/ts-custom-error?color=green)](https://bundlephobia.com/result?p=ts-custom-error)
13
14## Extend native Error to create custom errors
15
16`ts-custom-error` is a tiny (~500 bytes of minified & gzipped Javascript) package providing a `CustomError` class and a `customErrorFactory` function to easily extends native Error in node and evergreen browsers.
17
18It's written in Typescript and try to offer the best development and debug experiences: bundled in Javascript with Typescript definition files, map files and bundled js files for various environments: transpiled to es5 with commonjs, module and umd exports, the umd bundle is also available minified for easy import in browsers.
19
20## Why
21
22Because [extending native Error in node and in browsers is tricky](https://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript)
23```js
24class MyError extends Error {
25 constructor(m) {
26 super(m)
27 }
28}
29```
30 [doesn't work as expected in ES6](https://stackoverflow.com/questions/31089801/extending-error-in-javascript-with-es6-syntax-babel) and [is broken in Typescript](https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work).
31
32### Use `CustomError` class
33
34Simply extends and call `super` in you custom constructor.
35
36```ts
37import { CustomError } from 'ts-custom-error'
38
39class HttpError extends CustomError {
40 public constructor(
41 public code: number,
42 message?: string,
43 ) {
44 super(message)
45 }
46}
47
48...
49
50new HttpError(404, 'Not found')
51```
52You may want more advanced contructor logic and cutom methods, see [examples](https://github.com/adriengibrat/ts-custom-error/tree/master/src/example)
53
54### Use `customErrorFactory` factory
55
56*Custom error contructor returned by the factory pass the same unit tests as Class constructor.*
57
58Factory still allows custom logic inside constructor:
59
60```ts
61import { customErrorFactory } from 'ts-custom-error'
62
63const HttpError = customErrorFactory(function HttpError (code: number, message= '') {
64 this.code = code
65 this.message = message
66})
67
68...
69
70new HttpError(404, 'Not found')
71```
72
73Custom Error from `customErrorFactory` can:
74- Be called as a simple function
75```ts
76HttpError(404, 'Not found')
77```
78- Extend any native Error, using the second optional argument
79```ts
80import { customErrorFactory } from 'ts-custom-error'
81
82const ValidationError = customErrorFactory(function ValidationError (message= 'Invalid parameter') {
83 this.message = message
84}, TypeError)
85```
86
87### Known limitations
88
89#### Minification and transpilation mangle custom Error names.
90Unexpected results are:
91- Minified identifiers in place of custom Error name in Stacktrace
92- Wrong error recognition where using errors name (bad practice) instead of `instanceof`
93
94You may fix this behaviour by:
95- Using [uglifyjs options](https://github.com/mishoo/UglifyJS2/blob/harmony/README.md) `--mangle 'except=["MyError"]'` (need to specify all custom error names) or `--keep_fnames` / `--keep_classnames` (nothing to specify but your bundle size will be larger)
96- Setting explicitly error name:
97
98```ts
99import { CustomError } from 'ts-custom-error'
100
101class MyError extends CustomError {
102 constructor() {
103 super()
104 // Set name explicitly as minification can mangle class names
105 Object.defineProperty(this, 'name', { value: 'MyError' })
106 }
107}
108```
109
110```ts
111import { customErrorFactory } from 'ts-custom-error'
112
113const MyError = customErrorFactory(function MyError () {
114 // Set name explicitly as minification can remove function expression names
115 Object.defineProperty(this, 'name', { value: 'MyError' })
116})
117```
118
119### Usefull development commands
120
121- Watch source changes and run corresponding unit tests
122```
123npm start
124```
125
126- Run all unit tests
127```
128npm test
129```
130
131- Get coverage report
132```
133npm run coverage
134```
135
136- Format staged code and run commitizen (enforce commit message convention)
137```
138npm run commit
139```
140
141### Automate all the things
142
143⚠️ This project is mainly a pet project and its first purpose is to be a playground for various external services and tools:
144- opinionated code style mostly inspired from [standardjs](https://standardjs.com)
145- automatic code formating with [prettier](https://github.com/prettier/prettier)
146- code quality analysis by [codeclimate](https://codeclimate.com/github/adriengibrat/ts-custom-error)~~, [bithound](https://www.bithound.io/github/adriengibrat/ts-custom-error)~~ & [bettercodehub](https://bettercodehub.com/results/adriengibrat/ts-custom-error)
147- automated continuous integration on [travis](https://travis-ci.org/adriengibrat/ts-custom-error)
148- automated semantic versioning with [changelog](CHANGELOG.md) generation and release deployment on [npm](https://www.npmjs.com/package/ts-custom-error) and [github](https://github.com/adriengibrat/ts-custom-error/releases) thanks to [semantic-release](https://github.com/semantic-release/semantic-release)
149
150## Licence
151
152Starting [version 3.0.0](https://github.com/adriengibrat/ts-custom-error/releases/tag/v3.0.0) this project is under [MIT licence](LICENSE), there are no code change between [version 2.2.2](https://github.com/adriengibrat/ts-custom-error/releases/tag/v2.2.2) and [version 3.0.0](https://github.com/adriengibrat/ts-custom-error/releases/tag/v3.0.0) but changing licence was considered as a breaking change. All [versions < 3.0.0](https://github.com/adriengibrat/ts-custom-error/releases) are under [WTFPL](http://www.wtfpl.net).
153
154## Similar packages
155
156- [![custom-error](https://badge.fury.io/js/custom-error.svg)](https://www.npmjs.com/package/custom-error) [custom-error](https://github.com/andrezsanchez/custom-error) provides a factory with custom name and parent error
157- [![custom-errors](https://badge.fury.io/js/custom-errors.svg)](https://www.npmjs.com/package/custom-errors) [custom-errors](https://github.com/techjacker/custom-errors) provides a class and a factory with custom name and message, easy integration with with [express](https://github.com/expressjs/express) and (log)[https://github.com/visionmedia/log.js]
158- [![custom-error-generator](https://badge.fury.io/js/custom-error-generator.svg)](https://www.npmjs.com/package/custom-error-generator) [custom-error-generator](https://github.com/jproulx/node-custom-error) provides a factory with custom name, default properties and a constructor (node only)
159- [![custom-error-instance](https://badge.fury.io/js/custom-error-instance.svg)](https://www.npmjs.com/package/custom-error-instance) [custom-error-instance](https://github.com/Gi60s/custom-error-instance) provides a factory with custom name, properties and construction logic (! browser compatibility: redefine constructor name)
160- [![node-custom-errors](https://badge.fury.io/js/node-custom-errors.svg)](https://www.npmjs.com/package/node-custom-errors) [node-custom-errors](https://github.com/axyjs/node-custom-errors) provides factories to create abstract or concrete error with default message, an optional constructor function allow more custom properties/methods (node/chrome only, because no feature detection)
161- [![extendable-error](https://badge.fury.io/js/extendable-error.svg)](https://www.npmjs.com/package/extendable-error) [extendable-error](https://github.com/vilic/extendable-error) provides a class with clean stacktrace even in non v8 environments
162- [![extendable-error-class](https://badge.fury.io/js/extendable-error-class.svg)](https://www.npmjs.com/package/extendable-error-class) [extendable-error-class](https://github.com/brillout/extendable-error-class) provides simple class
163- [![extend-error](https://badge.fury.io/js/extend-error.svg)](https://www.npmjs.com/package/extend-error) [extend-error](https://github.com/jayyvis/extend-error) provides a factory attached to global Error object, allows custom name, code & message error
164- [![error-extend](https://badge.fury.io/js/eerror-extend.svg)](https://www.npmjs.com/package/error-extend) [error-extend](https://github.com/tilap/error-extend) provides a factory with custom name, default code & message properties, an optional init function allow more custom properties/methods