Stop 04 · JavaScriptTopics · 22/36

Error Handling

Part of the Frontend Developer Roadmap

In short

Networks fail, users type nonsense and APIs change without telling you. Good error handling means your app shows a helpful message instead of a blank white screen.

`try`/`catch`/`finally` and custom `Error` subclasses let you gracefully handle failures instead of letting them crash your app silently. Robust error handling should distinguish expected failures from programming bugs, preserve useful context, provide user-safe messages, and make failures observable during development.

The jaadu mascot relaxes in a dim room as a glowing inverter keeps the fan spinning.

Think of it like this

The hostel inverter

Power cuts happen. Without an inverter, everything goes dark. With one, the fans keep spinning and someone calls the electrician. try is normal power, catch is the inverter kicking in, and finally is switching off the main once it's over, cut or no cut.

Watch it happen

What happens when parseAge throws

push(try block)
try block

Top of the stack is coloured

1/10Code enters the try block.

The big ideas

What you need to know

try, catch, finally

Risky code goes in try. If it throws, catch gets the error. finally runs either way, good for cleanup.

Throw Error objects

throw new Error("message") gives you a message and a stack trace. Throwing plain strings loses the stack.

Custom error types

Extend Error to make ValidationError or NetworkError, then check with instanceof to handle each one differently.

Async needs await

try/catch only catches a promise's error if you await it inside the try block.

See it in code

Walk through the code

js
1class ValidationError extends Error {2  constructor(message) { super(message); this.name = "ValidationError"; }3}4function parseAge(text) {5  const age = Number(text);6  if (Number.isNaN(age)) throw new ValidationError("Age must be a number");7  return age;8}9try {10  parseAge("twenty");11} catch (err) {12  if (err instanceof ValidationError) console.log(err.message); // "Age must be a number"13  else throw err;              // not ours, let it go up14} finally {15  console.log("Done checking");16}

1/5A custom error type with its own name.

Only handle errors you understand. Anything else gets thrown again so it isn't silently hidden.

Save yourself the pain

Common mistakes

Oops

Writing an empty catch {} to make the red error go away.

Do this instead

That hides real bugs. At least log the error, and show the user something useful.

Oops

Wrapping fetch(url) in try/catch without await.

Do this instead

The try ends before the promise fails. Write await fetch(url) inside try, or add .catch to the promise.

Your mission

Make a form fail nicely

~20 min

Quick check

What happens? try { setTimeout(() => { throw new Error("x"); }, 0); } catch { console.log("caught"); }

Go deeper

  1. 1Wrap a risky operation (JSON parsing, a fetch call) in `try`/`catch`. Validate your understanding by applying it in a small practical example.
  2. 2Create a custom error class extending `Error` with extra context. Validate your understanding by applying it in a small practical example.
  3. 3Learn how errors propagate through `async` functions and Promise chains.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge