Either Type
The returned value from await mightFail
or mightFailSync
is an Either
type. This type has either an error
or a result
, never both.
Error
If an error is thrown from the wrapped function, then the Either
result will only contain an error
.
const [error, result] = await mightFail(Promise.reject("oh no"));
// error is an instance of Error with the message "oh no"
// result is undefined
const [error, result] = await mightFail(Promise.reject("oh no"));
// error is an instance of Error with the message "oh no"
// result is undefined
const [error, result] = await mightFail(Promise.reject("oh no"));
// error is an instance of Error with the message "oh no"
// result is undefined
const [error, result] = await mightFail(Promise.reject("oh no"));
// error is an instance of Error with the message "oh no"
// result is undefined
The wrapped functions will hopefully throw an error object, and your own code will hopefully throw an error object. However, if something else is thrown, then a new Error
will be created from the thrown value.
So no more if (error instanceof Error) { ... }
checks!
Result
If the wrapped function completes successfully, then the Either
result will only contain a result
.
const [error, result] = await mightFail(Promise.resolve("success"));
// error is undefined
// result is the result of the promise ("success" in this case)
const [error, result] = await mightFail(Promise.resolve("success"));
// error is undefined
// result is the result of the promise ("success" in this case)
const [error, result] = await mightFail(Promise.resolve("success"));
// error is undefined
// result is the result of the promise ("success" in this case)
const [error, result] = await mightFail(Promise.resolve("success"));
// error is undefined
// result is the result of the promise ("success" in this case)
Type safety
You never lose the type information of the result of the promise passed to mightFail
. As long as there is no error, the result will be whatever type was resolved from the promise or returned from the sync function.
async function example() {
if (Math.random() > 0.5) {
throw new Error("oh no");
}
return { example: "success" };
}
const [error, result] = await mightFail(example());
// error: Error | undefined
// result: { example: string } | undefined
if (error) {
// error: Error
return;
}
// result: { example: string }
console.log(result.example);
async function example() {
if (Math.random() > 0.5) {
throw new Error("oh no");
}
return { example: "success" };
}
const [error, result] = await mightFail(example());
// error: Error | undefined
// result: { example: string } | undefined
if (error) {
// error: Error
return;
}
// result: { example: string }
console.log(result.example);
async function example() {
if (Math.random() > 0.5) {
throw new Error("oh no");
}
return { example: "success" };
}
const [error, result] = await mightFail(example());
// error: Error | undefined
// result: { example: string } | undefined
if (error) {
// error: Error
return;
}
// result: { example: string }
console.log(result.example);
async function example() {
if (Math.random() > 0.5) {
throw new Error("oh no");
}
return { example: "success" };
}
const [error, result] = await mightFail(example());
// error: Error | undefined
// result: { example: string } | undefined
if (error) {
// error: Error
return;
}
// result: { example: string }
console.log(result.example);
Structure
The structure of the Either
type is a tuple or an object. Or a "go" tuple if you import from /go
const [error, result] = await mightFail(example());
// or
const {error, result} = await mightFail(example());
// or
import { mightFail } from 'might-fail/go'
const [result, error] = await mightFail(example());
const [error, result] = await mightFail(example());
// or
const {error, result} = await mightFail(example());
// or
import { mightFail } from 'might-fail/go'
const [result, error] = await mightFail(example());
const [error, result] = await mightFail(example());
// or
const {error, result} = await mightFail(example());
// or
import { mightFail } from 'might-fail/go'
const [result, error] = await mightFail(example());
const [error, result] = await mightFail(example());
// or
const {error, result} = await mightFail(example());
// or
import { mightFail } from 'might-fail/go'
const [result, error] = await mightFail(example());
No matter which structure you choose, the way you use the Either
type is the same.