Throwing an error manually
To create an error manually you write throw new Error("error text"). The constructor builds an error object, and the throw operator starts the exception handling machinery and looks for the nearest try...catch.
Theory
TL;DR
new Error("text")creates an error object, on its own it interrupts nothing.throwraises that exception and stops the current block.- The engine looks for the nearest
try...catch; if it finds one the error lands there, if not the program crashes. - Besides
Errorthere areTypeError,RangeError,ReferenceError,SyntaxErrorand other descendants. - Your own error type comes from
class ValidationError extends Error.
Quick example
try {
throw new Error("Something went wrong!");
} catch (err) {
console.log("caught:", err.message);
}Output:
caught: Something went wrong!How it works
new Error("text")creates an error object withname,messageandstack.throwraises (generates) that exception.- JavaScript interrupts the current block and looks for the nearest
try...catch. - If a handler is found, the error lands there. If not, the program terminates with an error message.
It matters that these are two separate steps: new Error(...) without throw just creates an object and interrupts nothing.
const err = new Error("just an object"); // nothing happens yet
throw err; // now the exception is raisedValidating input
The most common reason to throw manually is argument validation:
function divide(a, b) {
if (typeof a !== "number" || typeof b !== "number") {
throw new TypeError("Arguments must be numbers!");
}
if (b === 0) {
throw new Error("Division by zero is not allowed!");
}
return a / b;
}
try {
console.log(divide(10, 0));
} catch (e) {
console.log("Error:", e.message);
}Output:
Error: Division by zero is not allowed!Note the choice: a wrong type gets a TypeError, a broken business rule gets the base Error.
Built-in error types
You can throw not only Error but also its descendants:
throw new TypeError("Wrong type");
throw new RangeError("Value is out of range");
throw new ReferenceError("Undefined variable");They are all created the same way, through new ...Error("message"), and they all inherit from Error, so instanceof Error is true for each of them.
A custom error class
You can create your own error type by extending Error:
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
function validateUser(user) {
if (!user.name) {
throw new ValidationError("Name is required!");
}
}
try {
validateUser({});
} catch (e) {
console.log(`${e.name}: ${e.message}`);
}Output:
ValidationError: Name is required!A dedicated class is convenient because inside catch you can tell it apart from other errors with instanceof ValidationError and handle it differently.
You can throw anything, but you should not
Formally throw accepts any value:
throw "an arbitrary string";
throw 404;
throw { message: "failure", code: 123 };This is not recommended: such values have neither stack nor name, they break the usual error shape and make the code less predictable. Always prefer:
throw new Error("Message");And remember that a throw without a handler stops the program:
throw new Error("Critical failure!");
console.log("this line never runs");Output:
Uncaught Error: Critical failure!The tools in one place:
| What we use | Purpose |
|---|---|
throw | Raises an exception |
Error | The base error class |
TypeError, RangeError, ReferenceError | Specialised error types |
try...catch | Handles the error |
class CustomError extends Error | Creating your own errors |
Common mistakes
- Writing
new Error("...")withoutthrowand being surprised that execution continues. - Throwing strings or numbers instead of
Errorobjects, which leavescatchwith nostackand noname. - Forgetting
super(message)in a custom error class, which leavesmessageempty. - Not setting
this.namein a custom class, so the error shows up in logs as a plainError. - Throwing inside a
catchwith no outertry...catch, because nobody will catch that exception.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.