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

javascript Documentation

LOADING ENGINE...

Custom Exceptions

AI & DATA SCIENCE // custom-exceptions

Create custom error classes by extending Error. They support instanceof checks, custom properties, and clear error hierarchies.

Syntax

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

Deep Dive Course

Custom exception classes extend **Error** to add context-specific properties (HTTP status codes, validation field names, error codes). They integrate with try/catch and support **instanceof** checks, allowing catch blocks to handle different error types precisely. Always set `this.name` in the constructor.

1Understanding Custom Exceptions

Custom exception classes extend Error to add context-specific properties (HTTP status codes, validation field names, error codes). They integrate with try/catch and support instanceof checks, allowing catch blocks to handle different error types precisely. Always set this.name in the constructor.

💡

Create an error hierarchy: AppError → NetworkError, ValidationError, AuthError. Catch at the right level.

editor.html
class NetworkError extends Error {
  constructor(url, status) {
    super(`Failed to fetch ${url}: HTTP ${status}`);
    this.name = 'NetworkError';
    this.url = url;
    this.status = status;
  }
}

try {
  throw new NetworkError('/api/users', 503);
} catch (e) {
  if (e instanceof NetworkError) {
    console.log(e.name, e.status, e.url);
  }
}
localhost:3000

2Practical Example

Here is a real-world application of Custom Exceptions showing how it is used in production JavaScript code.

editor.html
class ValidationError extends Error {
  constructor(errors) {
    super('Validation failed');
    this.name = 'ValidationError';
    this.errors = errors; // { field: message }
  }
}

function validate(data) {
  const errors = {};
  if (!data.email?.includes('@')) errors.email = 'Invalid email';
  if (!data.name) errors.name = 'Name is required';
  if (Object.keys(errors).length) throw new ValidationError(errors);
}

try { validate({ email: 'bad', name: '' }); }
catch (e) { console.log(e.errors); }
localhost:3000

3Best Practices

Follow these guidelines when working with Custom Exceptions:

1. Always call super(message) first

2. Set this.name to the class name

3. Add relevant context properties (code, field, statusCode)

⚠️

Tip: Create an error hierarchy: AppError → NetworkError, ValidationError, AuthError. Catch at the right level.

editor.html
class NetworkError extends Error {
  constructor(url, status) {
    super(`Failed to fetch ${url}: HTTP ${status}`);
    this.name = 'NetworkError';
    this.url = url;
    this.status = status;
  }
}

try {
  throw new NetworkError('/api/users', 503);
} catch (e) {
  if (e instanceof NetworkError) {
    console.log(e.name, e.status, e.url);
  }
}
localhost:3000

Examples

Example 01Basic Usage
class NetworkError extends Error {
  constructor(url, status) {
    super(`Failed to fetch ${url}: HTTP ${status}`);
    this.name = 'NetworkError';
    this.url = url;
    this.status = status;
  }
}

try {
  throw new NetworkError('/api/users', 503);
} catch (e) {
  if (e instanceof NetworkError) {
    console.log(e.name, e.status, e.url);
  }
}
Example 02Advanced Example
class ValidationError extends Error {
  constructor(errors) {
    super('Validation failed');
    this.name = 'ValidationError';
    this.errors = errors; // { field: message }
  }
}

function validate(data) {
  const errors = {};
  if (!data.email?.includes('@')) errors.email = 'Invalid email';
  if (!data.name) errors.name = 'Name is required';
  if (Object.keys(errors).length) throw new ValidationError(errors);
}

try { validate({ email: 'bad', name: '' }); }
catch (e) { console.log(e.errors); }

Best Practices

  • Always call super(message) first
  • Set this.name to the class name
  • Add relevant context properties (code, field, statusCode)

Interview Question

How do you ensure instanceof works correctly with custom errors?

Hint: Prototype chain setup.

When extending Error with ES6 classes, instanceof works automatically because the prototype chain is set up correctly. However, when transpiling with older tools (Babel), you may need to manually set 'Object.setPrototypeOf(this, MyError.prototype)' in the constructor to fix instanceof. Modern environments (Node 12+, modern browsers) don't need this fix.

Exercises

MediumPractice using Custom Exceptions in a real scenario.
View Solution
class NetworkError extends Error {
  constructor(url, status) {
    super(`Failed to fetch ${url}: HTTP ${status}`);
    this.name = 'NetworkError';
    this.url = url;
    this.status = status;
  }
}

try {
  throw new NetworkError('/api/users', 503);
} catch (e) {
  if (e instanceof NetworkError) {
    console.log(e.name, e.status, e.url);
  }
}

Frequently Asked Questions

How do you ensure instanceof works correctly with custom errors?

When extending Error with ES6 classes, instanceof works automatically because the prototype chain is set up correctly. However, when transpiling with older tools (Babel), you may need to manually set 'Object.setPrototypeOf(this, MyError.prototype)' in the constructor to fix instanceof. Modern environments (Node 12+, modern browsers) don't need this fix.

Related Functions

throwError-Objectstrycatch