Code of the Day
IntermediateThe runtime

Error handling

try/catch, throwing errors, and failing safely.

JavaScript / TSIntermediate8 min read
Recommended first
By the end of this lesson you will be able to:
  • Catch errors with try/catch/finally
  • Throw Error objects for invalid situations
  • Handle errors in async code

When something goes wrong at runtime, JavaScript throws an error. Unhandled, it stops execution (you read these traces in the error-messages fundamentals lesson). try/catch lets you respond instead of crashing.

try / catch / finally

try {
  const data = JSON.parse(input);   // throws if input isn't valid JSON
  use(data);
} catch (err) {
  console.error("bad input:", err.message);
} finally {
  cleanup();   // runs either way — success or failure
}

If the try block throws, control jumps to catch with the error; finally always runs, which is the place for cleanup that must happen regardless.

Throw for invalid situations

When your code hits something invalid, throw an Error rather than returning a nonsense value — fail loudly and early (the "say what you mean" principle):

function setAge(age) {
  if (age < 0) {
    throw new Error("age cannot be negative");
  }
  return age;
}

Throw Error objects (not strings) — they carry a message and a stack trace, which is what makes debugging possible.

JavaScript — editable, runs in your browser

Errors in async code

Because await throws a rejected , the same try/catch works for async code — no special syntax:

try {
  const user = await loadUser(1);
} catch (err) {
  console.error("failed to load:", err.message);
}

Catch errors you can actually handle; don't wrap everything in an empty catch that hides bugs. An error you can't sensibly recover from is often best left to propagate so it's visible.

Where to go next

Last in this module: fetch and APIs — talking to the network, pulling everything in this track together.

Finished reading? Mark it complete to track your progress.

On this page