🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
JS MASTER CLASS /// MASTER THE ENGINE /// BUILD LOGIC /// ASYNC PATTERNS /// JS MASTER CLASS /// MASTER THE ENGINE ///

Custom Errors | JavaScript Tutorial - In-Depth Guide

Master custom error classes: extending Error correctly, adding structured metadata, preserving the prototype chain and instanceof checks, and designing an error hierarchy for a real application.

Total XP: 0|💻 javascript XP: 0

Skill Matrix

UNLOCK NODES BY LEARNING NEW TAGS.

System Hub

Core logic.

Quick Quiz //

When creating a custom error class, why is calling super(message) important?


🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.

Subclassing the built-in Error class lets you create domain-specific error types — ValidationError, NetworkError, AuthenticationError — that carry structured, meaningful information beyond a generic error message string.

1Custom Errors | JavaScript Tutorial - In-Depth Guide Part 1

Extending the built-in Error class with 'class MyError extends Error' creates a custom error type with its own name and, critically, working instanceof checks.

+
class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = 'ValidationError';
  }
}
localhost:3000
🚨

Extending Error

2Custom Errors | JavaScript Tutorial - In-Depth Guide Part 2

Custom errors can carry additional structured properties beyond just a message — like which field failed validation, or an HTTP status code.

+
class ValidationError extends Error {
  constructor(message, field) {
    super(message);
    this.name = 'ValidationError';
    this.field = field;
  }
}
throw new ValidationError('Must be a valid email', 'email');
localhost:3000

Carrying Structured Data

3Custom Errors | JavaScript Tutorial - In-Depth Guide Part 3

instanceof checks let calling code branch on the specific type of error that occurred, handling each kind appropriately.

+
try {
  validateForm(data);
} catch (err) {
  if (err instanceof ValidationError) {
    highlightField(err.field);
  } else {
    showGenericError();
  }
}
localhost:3000

instanceof Branching

4Custom Errors | JavaScript Tutorial - In-Depth Guide Part 4

In older transpilation setups (targeting pre-ES2015 output), extending Error can break instanceof — a known workaround explicitly resets the prototype.

+
class MyError extends Error {
  constructor(message) {
    super(message);
    Object.setPrototypeOf(this, MyError.prototype); // legacy transpile fix
  }
}
localhost:3000

The Prototype Chain Gotcha

5Custom Errors | JavaScript Tutorial - In-Depth Guide Part 5

A well-designed application defines a small hierarchy of custom error classes — often a common base error, extended by more specific subtypes — mirroring the different failure modes the app actually needs to distinguish.

+
class AppError extends Error {}
class NotFoundError extends AppError {}
class AuthError extends AppError {}

if (err instanceof AppError) { /* handle known app errors */ }
localhost:3000

Designing an Error Hierarchy

6Step-by-Step Breakdown

Extending the built-in Error class with 'class MyError extends Error' creates a custom error type with its own name and, critically, working instanceof checks.

Checkpoint: When creating a custom error class, why is calling super(message) important?

  • It ensures the base Error's message and stack trace behavior still works
  • It's optional and has no real effect

Custom errors can carry additional structured properties beyond just a message — like which field failed validation, or an HTTP status code.

instanceof checks let calling code branch on the specific type of error that occurred, handling each kind appropriately.

Checkpoint: Can instanceof be used to distinguish which specific custom error type was thrown?

  • Yes, this is the main benefit of a proper class hierarchy
  • No, all Error subclasses look identical to instanceof

In older transpilation setups (targeting pre-ES2015 output), extending Error can break instanceof — a known workaround explicitly resets the prototype.

A well-designed application defines a small hierarchy of custom error classes — often a common base error, extended by more specific subtypes — mirroring the different failure modes the app actually needs to distinguish.

Next, we'll explore 'Built-in Error Types'.

Level Up 🚀

Advanced cheat sheets, SEO tricks, and interview prep for this topic.

Browser Support

ChromeSupported

Fully supported.

FirefoxSupported

Fully supported.

SafariSupported

Fully supported.

EdgeSupported

Fully supported.

Accessibility (A11y)

1Map Custom Error Types to Clear, Actionable Accessible Messages

A ValidationError's structured `field` property lets you move focus directly to the specific invalid form field and announce a precise error message via aria-describedby, rather than a generic, unhelpful alert for screen reader users.

SEO Implications

  • 1

    No Direct SEO Effect

    Custom error classes are an application-code-quality concern; SEO relevance is limited to more reliable error handling preventing broken page states.

Best Practices

Always Call super(message) and Set this.name in a Custom Error

Skipping super() loses the base Error's message/stack handling; setting `this.name` explicitly ensures the error's string representation and logging tools correctly identify its specific type.

Design a Small, Purposeful Error Hierarchy Instead of One-Off Classes Everywhere

Grouping errors by how calling code needs to react to them (not by every minor variation) keeps the hierarchy useful and easy to reason about.

Frequent Bugs

THE BUG

Creating a custom error class but forgetting to call super(message), resulting in `error.message` being empty and the stack trace being unreliable.

THE FIX

Always call `super(message)` as the first statement in a custom error's constructor before setting any additional properties.

THE BUG

In an older transpiled build target, `err instanceof CustomError` unexpectedly returning false even though the error actually is a CustomError instance.

THE FIX

Add `Object.setPrototypeOf(this, CustomError.prototype)` right after the super() call as a defensive fix for older compilation targets.

Real-World Examples

A Structured API Error Class

A frontend app needed to distinguish network failures, authentication failures, and validation failures returned from its backend API, each requiring different UI handling.

class ApiError extends Error {
  constructor(message, statusCode) {
    super(message);
    this.name = 'ApiError';
    this.statusCode = statusCode;
  }
}

if (response.status === 401) {
  throw new ApiError('Unauthorized', 401);
}

Interview Prep

?Frequently Asked Questions

Pascual Vila

Pascual Vila

Frontend Instructor // Code Syllabus

Common Pitfalls & Errors

The Error //

Missing super(message) call in a custom error constructor

class MyError extends Error { constructor(msg) { super(msg); // required this.name = 'MyError'; } }

The Solution //

Always call super(message) first in the constructor before setting additional custom properties.

Lesson Glossary

[01]Custom Error Class

A class extending the built-in Error to represent a specific, domain-relevant failure type.

Code Preview
class X extends Error

[02]super(message)

A call to the parent Error constructor, required to correctly initialize message and stack.

Code Preview
super(msg)

[03]Error Hierarchy

A structured set of custom error classes, often with a shared base class, mirroring an app's failure modes.

Code Preview
AppError → ValidationError

[04]Structured Error Metadata

Additional properties (like a field name or status code) attached to a custom error beyond its message.

Code Preview
error.field

[05]instanceof

An operator checking whether an object was constructed by a specific class (or its subclasses).

Code Preview
err instanceof X

Continue Learning