The Big Picture
How it all fits together
The explicit-exceptions package provides stability to your project by allowing you to explicitly specify which exceptions a function call may provide, each step of the way.
In the README, we presented the following example:
Let's pick this apart and learn what each piece is doing.
Exceptions are designed to be easy to distinguish from one another. In this case, this instance can be distinguished from other exceptions by checking if its code
property equals "NotFound"
.
Only throw exceptions if you want the caller to be able to recover from it - if you've detected a programmer error (like you found yourself in an invalid state), then throw an instance of Error()
instead and let your program "crash early".
Any function that can throw instances of Exception should be decorated by wrap()
.
wrap()
will take a function and return a new one that captures any thrown exceptions or returned values, and wraps them into a Maybe instance.
Pro tip: If you want your wrapped function to have a name in error stack traces, you'll have to explicitly give it one like this:
Maybe
instances can only be retrieved from wrapped functions. They're designed to be a black box that holds the result of a wrapped function call. The only thing you can do with the Maybe
instance is unwrap it (with unwrap()
). In fact, the library will attempt to detect and warn you if you've forgotten to call unwrap()
on a Maybe
instance.
Here, getEntry()
is a wrapped function that will return a Maybe
instance. This Maybe instance holds details about how getEntry()'s inner function behaved during execution. unwrap()
will cause one of the following three actions to be performed:
If
getEntry()
inner function did not throw an exception during its execution, thenunwrap()
will simply return whatever getEntry() inner function returned.If
getEntry()
's inner function threw aNotFound
exception, then unwrap will cause it to be rethrown, because we've declared that we expected it in the second parameter to unwrap.If
getEntry()
were to throw a differentNotAvailable
exception that was not found in our list of expected exceptions, then unwrap will instead throw an instance ofError()
explaining that a programmer error has occured. This is called "escalating" the exception.
Note that it's ok, and even encouraged to have unwrap's expected-exceptions parameter not be an exhaustive list of exceptions that the wrapped function can provide. If you have no way of handling the exception, then omit it from the expected-exception list, and let it escalate.
Notice that getEntryOrDefault isn't getting wrapped with wrap()
. This is because the only exception being thrown inside (NotFound
) is also getting handled before reaching its caller.
interoperability with other exception systems
You may wish to have explicit-exceptions be an internal detail to your package, and keep your package users unaware of its use. This dedicated page explains how to achieve this.
Next Steps
Check out the API Reference to learn more about the finer details of each function. Or, go ahead and give it an install with npm i explicit-exceptions
. You may also be interested in the light version, which provides a simplified variation of this project, intended for those who would prefer maintaining around 100 lines of code themself instead of adding a new dependency to their project.
Last updated