trywrap
v1.2.1
Published
A utility module to handle async function errors gracefully.
Downloads
4,987
Maintainers
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 totrue
, the error will be rethrown after callingonError
.
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