Skip to main content

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.
  • throw raises 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 Error there are TypeError, RangeError, ReferenceError, SyntaxError and other descendants.
  • Your own error type comes from class ValidationError extends Error.

Quick example

javascript
try { throw new Error("Something went wrong!"); } catch (err) { console.log("caught:", err.message); }

Output:

text
caught: Something went wrong!

How it works

  1. new Error("text") creates an error object with name, message and stack.
  2. throw raises (generates) that exception.
  3. JavaScript interrupts the current block and looks for the nearest try...catch.
  4. 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.

javascript
const err = new Error("just an object"); // nothing happens yet throw err; // now the exception is raised

Validating input

The most common reason to throw manually is argument validation:

javascript
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:

text
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:

javascript
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:

javascript
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:

text
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:

javascript
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:

javascript
throw new Error("Message");

And remember that a throw without a handler stops the program:

javascript
throw new Error("Critical failure!"); console.log("this line never runs");

Output:

text
Uncaught Error: Critical failure!

The tools in one place:

What we usePurpose
throwRaises an exception
ErrorThe base error class
TypeError, RangeError, ReferenceErrorSpecialised error types
try...catchHandles the error
class CustomError extends ErrorCreating your own errors

Common mistakes

  • Writing new Error("...") without throw and being surprised that execution continues.
  • Throwing strings or numbers instead of Error objects, which leaves catch with no stack and no name.
  • Forgetting super(message) in a custom error class, which leaves message empty.
  • Not setting this.name in a custom class, so the error shows up in logs as a plain Error.
  • Throwing inside a catch with no outer try...catch, because nobody will catch that exception.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.