Things go wrong: bad input, failed requests, typos. Robust code expects failure and handles it deliberately.
try / catch / finally
try {
const data = JSON.parse('{"name": "Alice"}');
console.log(data.name);
} catch (error) {
console.error("Parse failed:", error.message);
} finally {
console.log("always runs — cleanup goes here");
}Since ES2019 the binding is optional if you don't need the error details:
try { risky(); } catch { fallback(); }See it end-to-end with a custom error type:
Know the built-in types
| Error | Cause |
|---|---|
ReferenceError |
accessing an undeclared variable |
TypeError |
calling a method on the wrong type (null.foo()) |
SyntaxError |
invalid code or malformed JSON |
RangeError |
value outside allowed range |
Custom classes extending Error carry domain meaning and work with
instanceof — catch specifically, and re-throw what you can't handle
(swallowing unknown errors hides bugs).
Async errors need async catches
An exception thrown inside a promise won't hit a surrounding sync try/catch —
use await inside try, or .catch():
try {
const data = await loadDashboard();
} catch (err) {
showRetryDialog(err);
}
fetchData().catch(err => log(err)).finally(() => hideSpinner());Debugging toolkit
console.table(rows); // array of objects as a table
console.time("render"); ... console.timeEnd("render");
console.group("details"); ... console.groupEnd();
debugger; // pauses DevTools execution right here
console.log(error.stack); // exact file:line trailBreakpoints in DevTools (Sources panel) beat scattered console.logs — you can inspect every variable at the pause point.
Knowledge Check
4 questions — test your understanding
When does finally run?
The right way to create a custom error type:
catch (err) { if (err instanceof ValidationError) ... else throw err } - why re-throw?
try { x(); } catch { fallback(); } - is this legal?
Course complete
You've gone from console.log("Hello") to closures, promises, DOM events
and custom errors — the core of practical JavaScript. Where next?
- Build something small, today. A todo list, a quiz, a unit converter. Chapter 6's task-list editor is a great starting point.
- TypeScript — JavaScript plus static types; the industry default for medium+ projects.
- A framework — React, Vue or Svelte for UIs; Node.js + Express for servers.
- Deepen the fundamentals — prototypes,
this, and the event loop reward a second pass more than any framework does.
Happy hacking!