A better way to handle errors
- File structure remains flat, unlike with nested try...catch
- Both data and errors are declared with
const, unlike with non-nested try...catch - Both data and errors are non-nullable, once an early return occurs if the other is null
- Both data and errors are available at the top level, unlike with try...catch or promises
- Work with errors that are always
Errorobjects by default, without compromising type-safety, unlike with try...catch or promises - TypeScript support with optional generic parameters for
dataanderrortypes
$ npm install betterrimport { betterr, betterrSync } from 'betterr';
// const { betterr, betterrSync } = require('betterr');
const { data: user, err } = await betterr(() => getUserOrThrow());
// user: User | null, err: Error | null
if (err) return;
return user;
// user: Userbetterrcan be used with both asynchronous and synchronous callbacksbetterrSynccan only be used with synchronous callbacks, but avoids wrapping the data in a promise, soawaitis not necessary
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 error) must extend the
Errorobject. It defaults toError.
/**
* const betterrSync: <TData, TError extends Error = Error>
* (callback: () => TData) =>
* | { data: TData; err: null }
* | { data: null; err: TError }
*/
const { data, err } = betterrSync<User, MyError>(() => ({ id: 1 }));
// data: User | null, err: MyError | null