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 |
|
18 | It'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 |
|
22 | Because [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
|
24 | class 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 |
|
34 | Simply extends and call `super` in you custom constructor.
|
35 |
|
36 | ```ts
|
37 | import { CustomError } from 'ts-custom-error'
|
38 |
|
39 | class HttpError extends CustomError {
|
40 | public constructor(
|
41 | public code: number,
|
42 | message?: string,
|
43 | ) {
|
44 | super(message)
|
45 | }
|
46 | }
|
47 |
|
48 | ...
|
49 |
|
50 | new HttpError(404, 'Not found')
|
51 | ```
|
52 | You 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 |
|
58 | Factory still allows custom logic inside constructor:
|
59 |
|
60 | ```ts
|
61 | import { customErrorFactory } from 'ts-custom-error'
|
62 |
|
63 | const HttpError = customErrorFactory(function HttpError (code: number, message= '') {
|
64 | this.code = code
|
65 | this.message = message
|
66 | })
|
67 |
|
68 | ...
|
69 |
|
70 | new HttpError(404, 'Not found')
|
71 | ```
|
72 |
|
73 | Custom Error from `customErrorFactory` can:
|
74 | - Be called as a simple function
|
75 | ```ts
|
76 | HttpError(404, 'Not found')
|
77 | ```
|
78 | - Extend any native Error, using the second optional argument
|
79 | ```ts
|
80 | import { customErrorFactory } from 'ts-custom-error'
|
81 |
|
82 | const 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.
|
90 | Unexpected 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 |
|
94 | You 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
|
99 | import { CustomError } from 'ts-custom-error'
|
100 |
|
101 | class 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
|
111 | import { customErrorFactory } from 'ts-custom-error'
|
112 |
|
113 | const 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 | ```
|
123 | npm start
|
124 | ```
|
125 |
|
126 | - Run all unit tests
|
127 | ```
|
128 | npm test
|
129 | ```
|
130 |
|
131 | - Get coverage report
|
132 | ```
|
133 | npm run coverage
|
134 | ```
|
135 |
|
136 | - Format staged code and run commitizen (enforce commit message convention)
|
137 | ```
|
138 | npm 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 |
|
152 | Starting [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
|