DEV Community

Cover image for Async/Await: Error Handling
11 4

Async/Await: Error Handling

Promises allowed us to catch the error by using an error handler in then block or using a catch block. Async/await has similar strategies.

Using catch with await

We await an async function (mostly, await works with anything that produces thenable). Async functions provide promises so we can still take advantage of a catch block.

const myPromise = async () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject("We ran into an error");
        }, 2000);
    });
}

const main = async () => {
    const response = await myPromise().catch((err) => {
        console.log(err); // We ran into an error
    })
}

main();

myPromise gets rejected after 2 seconds with a message. When we are awaiting for this promise, we can chain a catch block to handle the error.

Using catch when calling the function

We can also add the catch block when we are calling the async function.

const myPromise = async () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject("We ran into an error");
        }, 2000);
    });
}

const main = async () => {
    const response = await myPromise();
}

main().catch((err) => {
    console.log(err); // We ran into an error
});

Since main is an async function, it will return a promise so we can make use of a catch block! Using catch is smart, but it has a disadvantage. It will catch any error happening in the main function and not only the error while awaiting myPromise.

So if you had more code in the main function that could result in an error, this catch block would get that too.

Using a higher-order function

We can add such catch blocks when calling the function but imagine if you have a large number of async function that you call in your application. Adding catch block to each one of them will become tiring. You do need to handle errors, though.

This is where a higher-order function will come into play. A higher-order function takes a function as an input and returns a function. These are used to transform the input function (in simple terms).

const myPromise = async () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject("We ran into an error");
        }, 2000);
    });
}

const main = async () => {
    const response = await myPromise();
}

const handleError = (err) => {
    console.log(err); // We ran into an error
}

const addingErrorHandler = (fn, errorHandler) => {
    return function() {
        fn().catch(errorHandler);
    }
}

const mainFunctionWithErrorHandler = addingErrorHandler(main, handleError);

mainFunctionWithErrorHandler();

We have added three new things:

  1. handleError as a standard function to handle errors.
  2. addingErrorHandler as a higher-order function. It takes a function and adds error handling to it.
  3. mainFunctionWithErrorHandler converts the main function to a function that can handle error using our higher-order function.

Adding all the functions might seem like a lot of code at the moment because we are doing this for one function main. We will be able to reuse this error handler and higher-order function for x number of async functions in a large application.

Using a try/catch block

JavaScript provides us with try/catch block where you try a block of code and if an error occurs, catch it in the catch block. We can use this with async/await as well.

const myPromise = async () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject("We ran into an error");
        }, 2000);
    });
}

const main = async () => {
    try {
        await myPromise(); // try this code
    } catch (err) { // if it throws an error execute the catch block
        console.log(err); // We ran into an error
    }
}

main();

Try/catch is the easiest to technique to understand and implement. It is excellent in a not so complex application, but I do prefer higher-order functions as the application becomes bigger.

SurveyJS custom survey software

Simplify data collection in your JS app with a fully integrated form management platform. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more. Integrates with any backend system, giving you full control over your data and no user limits.

Learn more

Top comments (1)

Collapse
 
zhoupeihuang profile image
zhoupeihuang โ€ข

why not use decorator ?

nextjs tutorial video

Youtube Tutorial Series ๐Ÿ“บ

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series ๐Ÿ‘€

Watch the Youtube series

๐Ÿ‘‹ Kindness is contagious

Please leave a โค๏ธ or a friendly comment on this post if you found it helpful!

Okay