/ README.md
README.md
1 # Errawr! 2 3 Errawr is indubitably the cutest library to help you get help from your errors. It prints semi-structured messages, which is to say that its output is meant to be somewhere in between natural language and JSON. This is particularly freeing because constructing error messages that always read like natural language is a) hard, and b) pointless. A semi-structured approach also makes errors far easier to write and read errors occur due to issues which are difficult to print, like empty strings where non-empty strings are expected, and even errors which arise from unprintable characters. 4 5 The project is inspired by the `error.cause` feature of the Ecmascript spec as well as a few existing packages, namely [verror](https://www.npmjs.com/package/verror), [nerror](https://www.npmjs.com/package/nerror), and [pupa](https://www.npmjs.com/package/pupa). Its printing is done by [object-inspect](https://www.npmjs.com/package/object-inspect). 6 7 Errawr is unrelated to the Ruby package of the same (excellent) name. 8 9 ## Usage 10 11 <!-- prettier-ignore --> 12 ```js 13 import Errawr, { rawr, invariant } from 'errawr'; 14 15 function rave(system) { 16 invariant(system.status === 'up', rawr('The system is {system.status}'), { system }); 17 18 return '200 SBEMAILS'; 19 } 20 21 export default function main() { 22 try { 23 rave({ status: 'down' }); 24 } catch(e) { 25 // stringify your errors as far up the call stack as is possible. 26 console.error(Errawr.print(e)); 27 28 /* 29 Error: The system is {status: 'down'} 30 at rave:4:2 31 at main:11:4 32 */ 33 } 34 } 35 ``` 36 37 The above example uses the `invariant` shorthand, which is equivalent to: 38 39 ```js 40 if (system.status !== 'up') { 41 throw new Errawr(rawr('The system is {system.status}'), { 42 info: { system }, 43 }); 44 } 45 ``` 46 47 If you don't need or want templating you can always omit `rawr`. Note that it may still be useful to provide relevant info: though it won't end up in the logs it will still be visible to you while debugging. 48 49 ```js 50 new Errawr('The system is not up', { info: { system } }); 51 ``` 52 53 ## Differences with VError 54 55 If you're already familiar with VError, here's what's changed: 56 57 - `new VError(options, 'reason')` has become `new Errawr('reason', options)` 58 - `verror.cause()` is now `errawr.cause` (i.e. not a function). This aligns with the new spec. 59 - There is no `MultiError`. Instead use the builtin `AggregateError`. 60 - There is no distinction between `VError` and `SError`. Presentation details have no place at the bottom of a class hierarchy. Instead you should handle message interpolation yourself. You may use the provided `rawr` function to do basic interpolation. 61 - `VError.fullStack(error)` is `Errawr.print(error)` 62 - causes are now in now an iterable returned from `Errawr.chain(err)` 63 - Instead of `VError.findCauseByName(err)` use `find(hasName(name, cause), Errawr.chain(err))` 64 - Instead of `VError.hasCauseWithName(err)` use `some(hasName(name, cause), Errawr.chain(err))` 65 - `find` or `some` methods are provided by your favorite [iterator tools](https://github.com/iter-tools/iter-tools/blob/trunk/API.md). 66 - `constructorFn` is now called `topFrame` 67 - There is no strict mode. Serialization of interpolated values is best-effort.