Sven Slootweg 780b5946af | 4 years ago | |
---|---|---|
src/packages | 4 years ago | |
.eslintrc | 4 years ago | |
.gitignore | 4 years ago | |
README.md | 4 years ago | |
index.js | 4 years ago | |
notes.txt | 4 years ago | |
package.json | 4 years ago | |
yarn.lock | 4 years ago |
README.md
error-chain
Finally, a sensible way to deal with error handling in Javascript!
error-chain
lets you create custom error types, that you can 'chain' to provide more context without losing the original error. It also provides a number of utilities for dealing with these 'chained errors', including tools for filtering error types.
Work in progress! This is an experimental pre-release. All of the utilities are currently packaged into this single package to make iterating on the design easier, but they will eventually become separate packages under the @error-chain/*
namespace.
While semantic versioning is still followed in principle, and so it should be fine to use this package in production already, it being a pre-release means there's a slightly higher chance of unintended API breakage, the documentation is not complete yet, and there may be bugs or awkward APIs. But if that's still an improvement over what you're currently doing - and for many people it probably will be - you should feel free to use it anyway!
Library implementers: If you use error-chain
in your library (which you should!), please make sure to describe in the README that you are using it, and link to the below section. That will help your users understand how to work with these sorts of errors. While they can be handled like normal Error
objects, your users will be able to get much more information out of them with the right tools.
If you are trying to work with or understand a chained error
You may be using a library that uses error-chain
, and wonder what it's all about. Or maybe you got a pretty vague error, and it seems like there should be more information, but it's not quite visible. That's probably because the details are stored in what's called the "cause chain" - the chain of errors that led up to the one you're looking at.
This library provides a number of utilities to get the most out of these errors. These are:
- getContext(error): This is a function that retrieves all of the "context" of every error along the chain, and merges it into a single object for you to use. "Context" is basically all of the custom properties on the errors, like HTTP status codes, protocol-specific error codes, and so on.
- render(error): This is a function that, given an error (from
error-chain
or otherwise), produces a string that describes in detail what went wrong - it includes the original stacktrace from where the first error occurred, as well as a list of all the other errors in the chain, if any, to provide more context. For example, the source error may be "unable to open file", and a higher-level error might explain that this resulted in a failure to load the configuration. Note that this does not, by itself, log anything to the console - it just creates a string that you can log yourself, anywhere you want. - getChain(error): If you'd rather generate your own error display, or otherwise want to deal with the chain of errors, this function will give you the entire chain behind an error as an array, ordered from highest-level to lowest-level (source) error.
- match(rules): If you're trying to write error handling code that only handles specific errors (which you should!), you can use this function to produce a 'filter' for them, based on your own rules - which get applied to any error in the chain. This means that if you try to
match(CustomErrorType)
for example, that will not only match top-level errors of theCustomErrorType
, but any error that has aCustomErrorType
-error anywhere in its chain. The API is explained more below. - ... list to be completed ...
API
create(name, [options])
To be documented.
match(rules)
Given one or more rules
, this function will generate and return a so-called "predicate function" - ie. a function that takes an error as its argument, and then returns true
or false
depending on whether it matched. The rules
are applied to every error in the chain, not just the top-level one - and if any of them matches, the predicate returns true
.
In practice, you'll probably use this combined with something like Bluebird's catch
filtering feature:
doSomething().catch(match(HTTPError), (error) => /* ... */)
The rules
themselves can be one of the following kinds of values:
- An error type (constructor function or class): In this case, it will use
instanceof
on each error in the chain, to determine whether it's a match. - An object of properties: In this case, it will compare each error in the chain against the object, and consider it a match when all the (rule) properties match against the error. Only one error in the chain needs to match, but all of the properties need to match (excluding ones not specified in the rule).
- A function: In this case, it will run the function for each error in the chain, and consider it a match if it returns
true
for any of them.
You can also specify multiple values in the rules
, like so:
match([ CustomErrorType, { errorCode: "OH_NO" } ])
In that case, an error will only be considered a match if all of the rules match against it, on the same error in the chain.
is(error, rules)
Like match(rules)
, but instead of creating a predicate function, it directly returns true
or false
. Useful if you want to manually check the error type/shape.
rethrowAs(errorType, ... arguments)
To be documented.
chain(error, errorType, ... arguments)
To be documented.
getContext(error)
To be documented.
getChain(error)
To be documented.
render(error)
To be documented.