betterr
A better way to handle errors

Advantages
Unlike with try...catch or promises:
- Both data and errors are declared with const, available at the top level, and non-nullable (once the other is handled)
- Errors are always Error objects
Installation
$ npm install betterr
Usage
- Wrap any code that may throw
import { betterr } from 'betterr';
const [user, err] = await betterr(() => getUserWithId(1));
-
Avoid handling the error, and use optional chaining
const maybeName = user?.name;
-
Handle the error (interrupting the control flow), after which optional chaining is not needed
if (err) return;
const name = user.name;
Explanation
betterr / betterSync execute a callback and return a tuple with data (callback return value) and err (error during execution), one of which will be null depending on the success of the callback.
-
betterr can be used with both asynchronous and synchronous callbacks.
-
betterrSync can only be used with synchronous callbacks, but avoids wrapping the data in a promise so that await is not necessary.
TypeScript
Both betterr and betterrSync are generic.
- The callback return type must be assignable to the first generic parameter (for
data). It defaults to the callback return type.
- The second generic parameter (for
err) must extend the Error object. It defaults to Error.
const [user, err] = betterrSync<User, RangeError>(() => ({ id: 1 }));