Promise wrapper for easy error handling without try-catch
npm i await-catcher --save
Import the library into your JavaScript file:
import { awaitCatcher, awaitCatcherAsync } from 'await-catcher';
await-catcher benefits:
- Type checking with typeScript generics
- Cleaner & less code (no need for try/catch)
- Dynamic variable names, accepts all data types, and more...
- Use awaitCatcherAsync to pass a call-back instead of using await/async (see below screenshot)
/**
* #1 - Type checking with typeScript generics
*
* Notice how the types are being passed. await-catcher uses generics to validate the types
* If a type doesn't match the returned value, then await-catcher will return a type error at runtime and compile time!
*/
interface Type_1 {
test: string
}
let promise = Promise.resolve({test: "hi mom"})
let [ data , error ] = await awaitCatcher<Type_1>(promise);
console.log(data, error); // "hi mom, undefined
type Type_2 = Array<number>;
let array = [123, 321];
let [ data , error ] = await awaitCatcher<Type_2>(array);
console.log(data, error); // "[123, 321], undefined
let array2 = [123, "string"];
let [ data , error ] = await awaitCatcher<Type_2>(array2);
console.log(data, error); // undefined, Type error: Type 'string' is not assignable to type 'number'
/**
* #2 - Cleaner and less code
*
* Makes the code easier to read by eliminating the need to use try/catch
*/
// 👎 old way of doing things...
const confirmUserEmailById = async (userId) => {
const userData;
try {
userData = await UserModel.findById(userId);
} catch (err) {
console.log(err)
}
if (!data) {
return;
}
const ticketId;
try {
ticketId = await sendEmailTo(userData.email);
} catch (err) {
console.log(err)
}
if (!ticketId) {
return;
}
return `Confirmation has been sent to ${userData.email} successfully. The support ticket number is ${ticketId}`;
}
// 🔥 Now you can do it like this...
const confirmUserEmailById = async (userId) => {
const [ userData, userError ] = await awaitCatcher( UserModel.findById(userId) );
if (!userData || userError) return console.log(userError);
const [ ticketId, ticketError] = await awaitCatcher( sendEmailTo(userData.email) );
if (!ticketId || ticketError return console.log(ticketError);
return `Confirmation has been sent to ${userData.email} successfully. The support ticket number is ${ticketId}`;
}
/**
* #3 - Dynamic variables names
*
* awaitCatcher returns an array of [ data, error ] like this --> Either [ undefined, error ] or [ data, undefined ].
*
* Therefore, you can utilize the array destructuring feature in ES6 to name the returned value whatever you like.
*
* The below 3 examples demonstrate some of the data types that awaitCatcher() can handle
*/
// 1)
let data, error;
[ data, error ] = await awaitCatcher("I can pass anything to awaitCatcher :)");
console.log(data, error); // "I can pass anything to awaitCatcher", undefined
// 2)
// notice we are reusing the same varibleables (data & error) that were declared above
[ data, error ] = await awaitCatcher(Promise.reject("I don't need try/catch to handle rejected promises"))
console.log(data, error); // undefined, "I don't need try/catch to handle rejected promises"
// 3)
// other variable names can be used whenever needed
const [ anyVarName_data, anyVarName_error ] = await awaitCatcher( () => Promise.resolve("I can pass functions that return promises") )
console.log(anyVarName_data, anyVarName_error); // "I can pass functions that return promises", undefined
/**
* #4 - Use awaitCatcherAsync to pass a call-back instead of using await/async
*
* This is useful when you're not in an async function, but you still can use await-catcher
*/
/**
* awaitCatcherAsync is a wrapper for awaitCatcher that accepts a callback instead of aysnc/await
* @param promise
* @param cb
* @param options
*/
awaitCatcherAsync<Array<string>>(
callToGetData(),
(data, error) => this.setState({updateScreenData: data}),
options
);
type options = {
getByKeys?: String[]; // get key/values from object
getByKeysAndInvoke?: String[]; // get key/values from object and invoke functions
}
Evan Bacon, a great "markdown developer". (I stole this readme layout from him! 😁)