npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

trywrap

v1.2.1

Published

A utility module to handle async function errors gracefully.

Downloads

4,987

Readme

Trywrap

Trywrap is a lightweight utility module designed to simplify error handling in asynchronous functions. By wrapping functions, it provides a cleaner, more readable way to manage errors, reducing the need for repetitive try-catch blocks.

Installation

To install Trywrap, use npm:

npm install trywrap

Usage

Here's a basic example of how to use Trywrap. This example demonstrates handling errors with a fallback value and a global error handler:

const trywrap = require('trywrap');

async function testFn(value) {
    if (value < 0) throw new Error("Negative value");
    return `Success: ${value}`;
}

async function onError({ error, methodName, args }) {
    console.error(`Caught in ${methodName} with args ${JSON.stringify(args)}:`, error.message);
}

(async () => {
    const result = await trywrap(testFn, [10], { onError, fallback: "Default Value" });
    console.log(result); // Success: 10

    const failedResult = await trywrap(testFn, [-5], { onError, fallback: "Default Value" });
    console.log(failedResult); // Default Value
})();

API

trywrap(cb, props, options)

Parameters:

  • cb (Function, required): The async function to be executed.
  • props (Array, optional, default: []): Arguments to pass to the function.
  • options (Object, optional):
    • onError (Function): A callback function that is called with an object containing:
      • error: The error object.
      • methodName: The name of the function that threw the error.
      • args: The arguments passed to the function.
    • fallback (any): A value to return if an error occurs.
    • rethrow (boolean): If set to true, the error will be rethrown after calling onError.

Example Use Cases

1. Handling API Calls

In this example, Trywrap is used to handle errors during API calls, providing a fallback value if the call fails:

async function fetchData() {
    throw new Error("API failed");
}

const data = await trywrap(fetchData, [], {
    onError: ({ error, methodName, args }) => {
        console.error(`Caught in ${methodName} with args ${JSON.stringify(args)}:`, error.message);
    },
    fallback: []
});

console.log(data); // []

2. Handling Database Queries

Trywrap can also be used to manage errors in database queries, ensuring a fallback value is returned if an error occurs:

async function getUser(id) {
    if (id !== 1) throw new Error("User not found");
    return { id, name: "John Doe" };
}

const user = await trywrap(getUser, [2], {
    onError: ({ error, methodName, args }) => {
        console.error(`Caught in ${methodName} with args ${JSON.stringify(args)}:`, error.message);
    },
    fallback: null
});

console.log(user); // null

3. Rethrowing Errors

This example illustrates how to rethrow errors after handling them, allowing for further error processing:

async function riskyOperation() {
    throw new Error("Something went wrong");
}

async function onError({ error, methodName, args }) {   
    console.error(`Caught in ${methodName} with args ${JSON.stringify(args)}:`, error.message);
}

try {
    await trywrap(riskyOperation, [], { onError, rethrow: true });
} catch (err) {
    console.error("Error was rethrown:", err.message);
}

Traditional Nested Try-Catch vs. Trywrap

Traditional Nested Try-Catch

Traditionally, handling errors with nested try-catch blocks can become cumbersome and hard to maintain:

async function outerFunction() {
    try {
        // #action-1
        try {
            await innerFunction();
        } catch (innerError) {
            console.error("Inner error caught:", innerError.message);
        }
        // #action-2
        try {
            await innerFunction();
        } catch (innerError) {
            console.error("Inner error caught:", innerError.message);
        }
        // #action-3
        await actionFunction();
        // #action-4
        await innerFunction();
    } catch (outerError) {
        console.error("Outer error caught:", outerError.message);
        try {
            await recoveryFunction();
        } catch (recoveryError) {
            console.error("Recovery error caught:", recoveryError.message);
        }
    }
}

async function actionFunction() {
    return "Action function";
}

async function innerFunction() {
    throw new Error("Inner function error");
}

async function recoveryFunction() {
    throw new Error("Recovery function error");
}

outerFunction();

Using Trywrap

With Trywrap, the same logic is simplified, reducing the need for nested try-catch blocks and centralizing error handling:

async function outerFunction() {
    // #action-1
    await trywrap(innerFunction, [], { onError, fallback: "Fallback for action 1" });
    // #action-2
    await trywrap(innerFunction, []);
    // #action-3
    await trywrap(actionFunction, [], { onError, fallback: "Fallback for action 3" });
    // #action-4
    await trywrap(innerFunction, [], { onError, fallback: "Fallback for action 4" });
}

async function onError({ error, methodName }) {
    console.error("Error caught in", methodName, error.message);
}

async function actionFunction() {
    return "Action function";
}

async function innerFunction() {
    throw new Error("Inner function error");
}

async function recoveryFunction() {
    throw new Error("Recovery function error");
}

outerFunction();

Why Use Trywrap?

Cleaner Code: No more repetitive try-catch blocks.
Flexible: Customize error handling with callbacks and fallbacks.
Lightweight: Minimal overhead with just one function.
Works with Any Async Function: Use it with API calls, database queries, file operations, etc.

License

MIT