Skip to content

JavaScript Tutorial Asynchronous JavaScript

Error Handling in async/await Code

Lesson 145 of 258 2 min read By Deepak Paswan Updated Oct 4, 2026

With async / await, errors are handled with the usual try...catch. A rejected promise that you await becomes a thrown error at that line.

script.js
JS
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

function failingTask() {
  return wait(100).then(() => { throw new Error("Server not reachable"); });
}

async function main() {
  try {
    const data = await failingTask();
    console.log("never reached", data);
  } catch (error) {
    console.log("Caught:", error.message); // → Caught: Server not reachable
  } finally {
    console.log("Cleanup runs either way");
  }
}
main();

What is inside try

Put the await calls that might fail in try. The catch block runs for any error in the block: a rejected promise, a thrown error or a typo.

Do not forget to await

script.js
JS
const fail = () => Promise.reject(new Error("oops"));

async function main() {
  try {
    fail();                // error on purpose: no await, so the rejection is NOT caught here
    console.log("not caught by this try");
  } catch (error) {
    console.log("this will not run");
  }
}
main().catch(() => {});

Without await, the error escapes your try...catch and becomes an unhandled rejection. Remember: no await, no catching.

Rethrow what you cannot handle

script.js
JS
async function loadData() {
  try {
    throw new Error("Network down");
  } catch (error) {
    console.log("logging:", error.message);
    throw error;          // let the caller decide what to do
  }
}

loadData().catch(error => console.log("caller handles:", error.message));

Handling per call

Sometimes you want a fallback for one call and an error for another:

script.js
JS
async function getOrDefault(promise, fallback) {
  try {
    return await promise;
  } catch {
    return fallback;
  }
}

getOrDefault(Promise.reject(new Error("fail")), "default value").then(v => console.log(v)); // → default value

Unhandled rejections

If a promise rejects and nothing handles it, the browser logs Uncaught (in promise) in the console. During development, treat it as a bug: add a catch or a try...catch.

script.js
JS
window.addEventListener("unhandledrejection", event => {
  console.error("Unhandled rejection:", event.reason);
});

(A global listener is for logging and monitoring, not a replacement for handling errors where they happen.)

Where to catch

Handle an error where you can do something useful about it: show a message, retry, use a default. Lower-level functions can throw; the code that talks to the user catches.

lightbulb
Related
Handling Async Errors in the Error Handling chapter shows complete patterns, and Fetch HTTP Errors covers the special case of fetch.