error-handling

try / catch with await

Since await throws when the awaited promise rejects, standard try/catch is the idiomatic way to handle async errors inside an async function. A finally block runs on both success and failure paths.

try { await promise; } catch (err) { ... } finally { ... }

Parameters

Parameter Purpose
try Wrap the awaited call(s) to catch rejections
catch (err) err is the rejection reason (typically an Error)
finally Runs after try/catch — even on early return

Examples

async function load() {
  try {
    const res = await fetch('/api');
    return await res.json();
  } catch (err) {
    console.error(err);
    return null;
  }
}

Uniform handling for fetch errors and JSON-parse errors.

async function withCleanup() {
  const lock = await acquire();
  try {
    return await doWork(lock);
  } finally {
    await release(lock); // always runs
  }
}

finally handles cleanup on success, rejection, or thrown error.

// Common bug: not awaiting inside try
try {
  return fetchData(); // rejection escapes the try!
} catch (e) { /* never runs */ }

Without await, the promise rejection is not thrown synchronously and the catch is skipped.

Gotcha

You must await the promise inside the try — returning a promise without await lets its rejection escape the catch. try/catch cannot catch errors from unawaited fire-and-forget promises.

Related

← All JS Promise reference · async/await vs promises vs callbacks