JavaScript Tutorial · JavaScript Toolbox · Lesson 35 of 44
JavaScript Errors
Handle errors with try, catch and finally, and throw your own.
try...catch...finally
When code inside try throws, execution jumps to catch. finally runs whether or not there was an error — use it for cleanup:
try {
const user = null;
console.log(user.name);
} catch (err) {
console.log(err.name + ":", err.message.includes("null") ? "can't read a property of null" : err.message);
} finally {
console.log("cleanup runs either way");
}
Output
TypeError: can't read a property of null cleanup runs either way
Throwing errors
throw an Error (not a plain string) so you get a message and a stack trace. Built-in types include TypeError, RangeError and SyntaxError.
Custom errors
Extend Error to create error types your code can recognise:
class ValidationError extends Error {
constructor(field, message) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
function register(email) {
if (!email.includes("@")) throw new ValidationError("email", "Email is invalid");
return "registered";
}
for (const email of ["[email protected]", "nope"]) {
try {
console.log(register(email));
} catch (err) {
if (err instanceof ValidationError) {
console.log(`${err.name} on ${err.field}: ${err.message}`);
} else {
throw err;
}
}
}
Output
registered ValidationError on email: Email is invalid
Only catch errors you can handle meaningfully. Swallowing every error with an empty catch {} hides bugs.
Test yourself
Which block runs whether or not an error was thrown?
catchfinallyelsealways
Show answer
Answer: finally