JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 15431
  • Score
    100M100P100Q140981F
  • License MIT

A simple, type-safe wrapper for handling errors without try-catch blocks.

Package Exports

  • p-safe

Readme

p-safe
CI NPM Version MIT License npm bundle size Install Size

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 const instead of declaring let outside try/catch blocks.
  • Better Type Inference: Strictly type your errors instead of dealing with any or unknown in 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.