JavaScript Error Handling
JavaScript error handling lets your program respond to problems instead of crashing. When something goes wrong, JavaScript throws an error object; you catch it with try...catch and decide what to do.
try...catch
Code in try runs normally. If any line throws, execution jumps to catch, which receives the error.
try {
const data = JSON.parse("{ bad json }");
console.log(data);
} catch (err) {
console.log("Could not parse:", err.name);
}
console.log("The program keeps running");Could not parse: SyntaxError The program keeps running
finally
finally runs whether or not an error happened. It is the place for cleanup, such as hiding a loading spinner.
function divide(a, b) {
try {
if (b === 0) throw new Error("Cannot divide by zero");
return a / b;
} catch (err) {
console.log("Error:", err.message);
return null;
} finally {
console.log("divide() finished");
}
}
console.log(divide(10, 2));
console.log(divide(1, 0));divide() finished 5 Error: Cannot divide by zero divide() finished null
Throwing Custom Errors
Throw your own errors with throw new Error(message). For different kinds of failures, extend Error into custom classes and check them with instanceof. The cause option links an error to the one that caused it.
class ValidationError extends Error {
constructor(field, message) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
function register(age) {
if (age < 13) throw new ValidationError("age", "Must be at least 13");
return "Registered";
}
try {
register(10);
} catch (err) {
if (err instanceof ValidationError) console.log(err.field, "->", err.message);
else throw err;
}age -> Must be at least 13
Built-in Error Types
- ReferenceError: using a variable that does not exist
- TypeError: wrong type, e.g. calling undefined as a function
- SyntaxError: invalid code or invalid JSON
- RangeError: number out of allowed range
Errors in Async Code
With async/await, wrap awaited calls in try...catch. With promise chains, use .catch(). Unhandled promise rejections show up in the console.
async function load() {
try {
await Promise.reject(new Error("Network down"));
} catch (err) {
console.log("Handled:", err.message);
}
}
load();Handled: Network down
Frequently asked questions
Should I wrap all my code in try catch?
No. Catch errors where you can actually handle them, like showing a message or retrying. Catching everything hides bugs.
Can I throw a string instead of an Error?
You can, but you lose the stack trace and the name/message properties. Always throw Error objects.
Does try catch work with setTimeout?
Not around it. The callback runs later, outside the try. Put the try...catch inside the callback, or use promises with await.