The fact that error handling in JavaScript is an afterthought with infinite variations of how it should be properly dealt with like try {} catch(e) {}
, .catch()
, .on("error", fn)
, and many more.
A Rustism (an idea/solution coming from Rust Lang) which does exactly that. It encodes a variable in a Result type that can be either the actual variable or an error.
By returning a resulti
from the function that might error in your library you give people a straightforward methodology of dealing with errors of any type.
This module is distributed via npm which is bundled with node and should be installed as one of your project's dependencies
:
npm install --save resulti
You can use it anywhere to encode a value that could potentially be an error.
Example:
import { ok, err } from "resulti";
// or
const { ok, err } = require("resulti");
const resultiWithOk = ok("myVal");
const resultiWithErr = err(Error("myError"));
A common place could be in interloping with normal async functions (if you're writing a library with an async function and using resulti
you should always resolve to a resulti
)
import { ok, err } from "resulti";
// or
const { ok, err } = require("resulti");
async function example() {
const couldBeError = await doSomethingAsync.then(ok).catch(err);
if (couldBeError.isOk()) {
const val = couldBeError.unwrap(); // Unwarp value from resulti
// Handle concrete val
} else {
const val = couldBeError.unwrapErr(); // Unwrap error value to handle it as appropriate
// Handle concrete error
}
}
The above pattern is rather common that resulti
offers a way to simplify it
import { resultify } from "resulti";
// or
const { resultify } = require("resulti");
async function example() {
const couldBeError = await resultify(doSomethingAsync);
// ...
}
ok(val)
, a function for creating a resulti
ok variant. Equivalent to resulti(val)
err(val)
, a function for creating a resulti
error variant. Equivalent to resulti(undefined, val)
resulti
, a function for creating resulti
s. Has few methods built on it for convenience:
resulti(okVariant, errVariant)
:
-
resulti.isOk()
: Returns true ifresulti
has an ok variant otherwise false. -
resulti.isErr()
: Returns true ifresulti
has an error variant otherwise false. -
resulti.unwrap()
: Returns the value ofresulti
's ok variant. Otherwise throws. -
resulti.unwrapErr()
: Returns the value ofresulti
's error variant. Otherwise throws. -
resulti.unwrapOr(defaultValue)
: Returnsresulti
's ok variant if it exists otherwisedefaultValue
passed to it. -
resulti.unwrapOrElse(fn)
: Returnsresulti
's ok variant if it exists or the return value of callingfn
with the error variant. -
resulti.expect(errMsg)
: Returns the value ofresulti
's ok variant. Otherwise throws errMsg. -
resulti.expectErr(errMsg)
: Returns the value ofresulti
's error variant. Otherwise throwserrMsg
. -
resulti.map(fn)
: maps the ok variant of aresulti
. Does nothing if ok variant doesn't exist. -
resulti.mapErr(fn)
: maps the error variant of aresulti
. Does nothing if error variant doesn't exist. -
resulti.mapOrElse(fn1, fn2)
: maps the ok variant of aresulti
withfn1
. Otherwise maps the error variant withfn2
. -
resulti.and(val)
: Returnsval
if ok variant exists otherwise returns theresulti
itself. -
resulti.andThen(fn)
: Returns the return value of callingfn
with ok variant if it exists, otherwise returns theresulti
itself. -
resulti.or(val)
: Returnsval
if error variant exists otherwise returns theresulti
itself. -
resulti.orElse(fn)
: Returns the return value of callingfn
with ok variant if it exists, otherwise returns theresulti
itself.
resultify
: a utility for turning promises into promises that ALWAYS resolve into a resulti
:
resultify(promise, mapOk, mapErr)
: Both mapOk and mapErr are optional and need to be functions if provided. They simply map the resulti in both its variants.
isResulti(val)
: is a utility function to determine if a val
is a resulti
or not.
MIT