1. Introduction
Error handling is the mechanism JavaScript gives you to detect, report, and recover from unexpected conditions at runtime — a network request that fails, an argument of the wrong type, or a value that falls outside an allowed range. Instead of letting a script crash silently or halt execution entirely, JavaScript lets you throw an Error object describing what went wrong and catch it somewhere else in the call stack to handle it gracefully.
Cricket analogy: When a run-chase calculation hits a divide-by-zero on a rain-abandoned match, error handling lets JavaScript throw an Error describing the problem and catch it elsewhere in the call stack instead of crashing the whole scoring app.
2. Syntax
try {
// code that may throw an exception
riskyOperation();
} catch (error) {
// handle the error
console.error(error.message);
} finally {
// always executes, error or not
cleanup();
}
// Throwing an error manually
throw new Error("Something went wrong");
// Common built-in error types
new TypeError("Wrong type");
new RangeError("Value out of range");
new ReferenceError("Variable is not defined");
new SyntaxError("Invalid syntax");3. Explanation
Every Error object has at minimum a name and a message property. When you write throw new Error("..."), the JavaScript engine stops normal execution and starts unwinding the call stack looking for a catch block that can handle it. If none is found, the error propagates to the top level and (in a browser) is printed to the console or (in Node.js) crashes the process.
Cricket analogy: A throw new Error('Invalid delivery') is like an umpire signaling a no-ball and stopping play mid-over; the appeal unwinds up through fielders and captain (the call stack) looking for someone (a catch block) who can rule on it, or it reaches the match referee and halts the game.
JavaScript ships several built-in Error subclasses that describe common failure categories: TypeError (an operation was performed on a value of the wrong type, e.g. calling a non-function), RangeError (a numeric value is outside its allowed range, e.g. an invalid array length), ReferenceError (a reference to a variable that doesn't exist), and SyntaxError (malformed code, often thrown by JSON.parse on invalid JSON). Choosing the right built-in type — or creating your own — makes errors easier to identify programmatically with instanceof or error.name.
Cricket analogy: Calling a fielder's name as if it were a function (fielder()) throws a TypeError, an invalid over count of -2 throws a RangeError, referencing an unregistered player variable throws a ReferenceError, and malformed scorecard JSON throws a SyntaxError from JSON.parse.
A plain try-catch around synchronous code will NOT catch errors thrown inside a callback (e.g. inside setTimeout) or inside a rejected Promise. Asynchronous errors must be handled with .catch() on the promise chain, or by wrapping an await expression in try-catch inside an async function — a try-catch around the async call itself is not enough if the error happens later, on a different turn of the event loop.
4. Example
function parseNumber(input) {
if (typeof input !== "string") {
throw new TypeError("Input must be a string");
}
const num = Number(input);
if (Number.isNaN(num)) {
throw new RangeError(`"${input}" is not a valid number`);
}
return num;
}
const inputs = ["42", "abc", 100];
for (const value of inputs) {
try {
const result = parseNumber(value);
console.log("Parsed:", result);
} catch (err) {
console.log(`${err.name}: ${err.message}`);
}
}5. Output
Parsed: 42
RangeError: "abc" is not a valid number
TypeError: Input must be a string6. Key Takeaways
- Use
throwto signal a failure and try-catch to intercept it before it crashes the program. - Prefer the specific built-in error type (TypeError, RangeError, ReferenceError, SyntaxError) that matches the failure, rather than a generic Error.
- Every Error object exposes
name,message, and (in most engines) astacktrace for debugging. - Synchronous try-catch does not catch errors from callbacks or rejected Promises — those need
.catch()or async/await. - Unhandled errors propagate up the call stack and terminate the script (or the process in Node.js) if never caught.
Practice what you learned
1. Which built-in error is thrown when you call `Number.parseInt` — wait, actually thrown when you access an undeclared variable?
2. What two properties does every Error object have at minimum?
3. Which error type is most appropriate for `new Array(-1)`?
4. What happens if an error is thrown and no try-catch block exists anywhere in the call stack?
5. Does wrapping a `setTimeout` call in a plain try-catch catch errors thrown inside the timeout callback?
6. Which error would `JSON.parse("{ invalid }")` throw?
Was this page helpful?
You May Also Like
try-catch in JavaScript
The mechanics of the try, catch, and finally blocks, including execution order and how finally interacts with return statements.
Custom Errors in JavaScript
Building your own Error subclasses by extending the built-in Error class to represent domain-specific failures.
Promises in JavaScript
Understand the Promise object, its three states, and how .then/.catch/.finally chaining replaces nested callbacks.
async/await in JavaScript
Learn how async/await provides synchronous-looking syntax for working with Promises, including error handling with try/catch.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics