Custom Error classes & error.cause

Errors with meaning

Lesson 13 of 20 · 10 min · Module 4: Reliable code

A plain Error only carries a message. Your own error classes tell callers exactly what went wrong and which field caused it, so they can show helpful messages instead of "something failed".

Start this lesson →

Free. No installation: you write and run the code in your browser, and it is checked automatically.

By the end, you’ll be able to…

  • Create a custom error class
  • Attach details to an error
  • Handle specific errors with instanceof

The idea

Extend Error, call super(message), and set this.name. Extra properties such as field carry details. Catch code can then check error instanceof ValidationError. new Error(msg, { cause }) keeps the original error that triggered a new one.

class NotFoundError extends Error {
  constructor(what) {
    super(what + " not found");
    this.name = "NotFoundError";
  }
}
try { throw new NotFoundError("Course"); }
catch (e) { console.log(e.name, e.message, e instanceof Error); }

01Extend Error

class ValidationError extends Error gives you a message, a stack trace, and everything else a normal error has. Setting this.name makes logs show ValidationError instead of Error.

02Catch precisely

A form can catch a ValidationError and highlight error.field, while any other error (a network problem, a bug) is reported differently instead of being shown as a form mistake.

try { throw new RangeError("too big"); }
catch (e) {
  console.log(e instanceof RangeError, e instanceof TypeError);
}
Output
true false

03Keep the cause

When you turn a low-level error into a clearer one, pass { cause: original } as the second argument of the Error constructor. Debugging tools then show both.

Your turn

Write ValidationError (extends Error, name is "ValidationError", and a field property). Write validateSignup({ email, password, age }) that returns { email, age } with the email trimmed and lowercased and age as a number. Throw a ValidationError with field "email" if there is no @ with text on both sides, "password" if it is shorter than 8 characters, and "age" unless age is a whole number from 16 to 120 (strings like "21" are accepted).

What the checks look for

  • ValidationError is a real Error with a name and field
  • Returns cleaned data for valid input
  • Reports the field that failed
  • Accepts the age limits
Try it in the editor →

Take this with you

Specific error types make failures easy to handle correctly.

Go a little further

Collect every problem instead of stopping at the first one, and throw one error with a list of fields.

Learn JavaScript Intermediate for free

20 short lessons with real code and instant checks.

See the whole course →