p-safe
p-safe provides a clean and elegant way to safely handle promise rejections and function errors without messy try/catch blocks.
Benefits
- Avoid Scoping Issues: Keep variables in local scope using
constinstead of declaringletoutsidetry/catchblocks. - Better Type Inference: Strictly type your errors instead of dealing with
anyorunknownin catch blocks. - Clean Control Flow: Promotes a "fail-fast" pattern with flatter, more readable code that's easier to maintain.
- Flexible Patterns: Support for both Result pattern (
trySafe) and Optional pattern (tryIgnore) depending on your needs. - Async Native: Fully capable of wrapping both synchronous and asynchronous functions elegantly.
Installation
npm install p-safe
Install using your favorite package manager
pnpm
pnpm install p-safe
yarn
yarn add p-safe
Usage
Result Pattern (trySafe)
Safely execute an operation and get back a structured object. This is best when you need to handle the error specifically.
import { trySafe } from 'p-safe';
const { data, error } = await trySafe(() => fetchUser(id));
if (error) {
return console.error('Failed to load user:', error.message);
}
console.log('User name:', data.name);
Optional Pattern (tryIgnore)
Use this for "nice-to-have" operations where you don't care why it failed, you just want the result or null.
import { tryIgnore } from 'p-safe';
// If JSON is invalid, config will simply be null
const config = await tryIgnore(() => JSON.parse(maybeJson));
// If the file doesn't exist, it returns null instead of throwing
const stats = await tryIgnore(() => fs.promises.stat('./optional-file.txt'));
Manual Resolve/Reject
Use the resolve and reject callbacks for granular control, similar to the Promise constructor.
const { data, error } = await trySafe(async (resolve, reject) => {
const resp = await fetch(url);
if (!resp.ok) return reject(new Error('Fetch failed'));
resolve(await resp.json());
});
Strict Typing
Leverage TypeScript to ensure your error handling is robust and type-safe by defining custom error types.
class MathError extends Error {}
const { data, error } = await trySafe<number, MathError>(
async (resolve, reject) => {
if (num < 0) return reject(new MathError('Negative number'));
resolve(Math.sqrt(num));
}
);
// error is typed as MathError | undefined
// data is typed as number | undefined
Documentation
For all configuration options, please see the API docs.
Contributing
Want to contribute? Awesome! To show your support is to star the project, or to raise issues on GitHub.
Thanks again for your support, it is much appreciated!
License
MIT Shahrad Elahi and contributors.