diff --git a/README.md b/README.md index 042adef..129890f 100644 --- a/README.md +++ b/README.md @@ -23,35 +23,79 @@ npm install @nkp/error ```html
- + ``` ## Usage +### On Error instances + +When an instance of `Error` is thrown, coerceError does nothing + ```ts +import { coerceError } from '@nkp/error'; + +function doWork() { + throw new Error('something went wrong'); +} try { - doSomeWork(); -} catch (_err) { - const err = coerceError(_err); - console.log('Error:', err); + doWork(); +} catch (_err: unknown) { + const err: Error = coerceError(_err); + console.error(err); + // Error: something went wrong + // at doWork (... + // at ... } ``` -## Notes +### On Non `Error` Instance `coerceError` does its best to maintain the stack trace of the thrown error. If a non `Error` instance is thrown then JavaScript cannot infer the call-stack for it. For example: ``` ts -try { throw 'untraceable'; } -catch(error) { assert(typeof error === 'string') +import { coerceError } from '@nkp/error'; +const message = 'untraceable'; +try { + // throw a string instead of of an Error instance + throw message; +} +catch(_error) { + console.log(typeof _error); // 'string' + const error = coerceError(_error); + console.log(error.message === message); // true +} ``` in this case, since a `string` is thrown and not an `Error` instance, there is no way to obtain the stack trace from the thrown point. Instead, `coerceError` will start the stack trace in the `catch` block. +### On Error-like Objects + +An error-like object is one with a string `message` property. + +Error-like objects that don't inherit from `Error` have their non-function properties (& properties from their prototype chain except `Object.prototype`) shallow copied onto a new Error instance. Function properties are not copied because copying bound functions may cause confusion when if mutating the error objects. + +```ts +const throwable = { + message: 'someting went wrong', + code: 50, + fn: () => {}, +}; +try { + throw throwable; +} catch (_error) { + const error = coerceError(_error); + console.log(throwable === error); // false; + console.log(error instanceof Error); // true + console.log((error as any).code === 50); // true + console.log(!('fn' in error)); // true +} +``` + ## Publishing To a release a new version: diff --git a/__tests__/readme.spec.ts b/__tests__/readme.spec.ts new file mode 100644 index 0000000..fe793fd --- /dev/null +++ b/__tests__/readme.spec.ts @@ -0,0 +1,54 @@ +/* eslint-disable @typescript-eslint/no-empty-function */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { coerceError } from '../src/index'; + +describe('readme examples should work', () => { + beforeEach(() => { + // ignore warnings + // eslint-disable-next-line @typescript-eslint/no-empty-function + jest.spyOn(console, 'warn').mockImplementation(() => {}); + }); + + it('On Error Instances', () => { + function doWork() { + throw new Error('something went wrong'); + } + try { + doWork(); + } catch (_err: unknown) { + const err: Error = coerceError(_err); + expect(err.stack).toMatch(/^ *Error: something went wrong/); + // Error: something went wrong + // at doWork (... + // at ... + } + }); + + it('On Non `Error` Instances', () => { + const message = 'untraceable'; + try { + // throw a string instead of of an Error instance + throw message; + } + catch(_error) { + expect(typeof _error).toBe('string'); // 'string' + const error = coerceError(_error); + expect(error.message === message).toBe(true); // true + } + }); + + it('On Error-like objects', () => { + try { + throw { + message: 'someting went wrong', + code: 50, + fn: () => {}, + }; + } catch (_error) { + const error = coerceError(_error); + expect(error instanceof Error).toBe(true); // true + expect((error as any).code).toBe(50); // true + expect(!('fn' in error)).toBe(true); // true + } + }); +}); diff --git a/changelog.md b/changelog.md index 81a8810..6e8a5cd 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,13 @@ # Changelog +## 0.0.6 - 2021-06-29 + +### Changed + +- Upgraded readme +- Added tests for readme examples +- Minified export + ## 0.0.5 - 2021-06-29 ### Changed diff --git a/config/rollup.config.js b/config/rollup.config.js index 24e0c90..e1801bd 100644 --- a/config/rollup.config.js +++ b/config/rollup.config.js @@ -34,7 +34,7 @@ export default [ resolve(), commonjs(), typescript({ tsconfig: 'config/tsconfig.build.json', }), - // terser(), + terser(), ], }, ]; diff --git a/package.json b/package.json index eaf4894..a6f5284 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nkp/error", - "version": "0.0.5", + "version": "0.0.6", "description": "Coerce an unknown error into an instance of the JavaScript Error class", "main": "cjs/index.js", "module": "es/index.js",