JavaScript Fundamentals / Error Handling

Custom Error Class

✅ What Are Custom Error Classes?

JavaScript provides built-in error types like Error, TypeError, RangeError, etc.

But sometimes you want to define your own specific error types to represent domain-specific problems.

👉 That’s where custom error classes come in.


🧱 Syntax

We create a custom error class by extending the built-in Error class using class syntax.

class MyCustomError extends Error {
  constructor(message) {
    super(message);         // Call parent constructor (Error)
    this.name = "MyCustomError";  // Set custom error name
  }
}
class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = "ValidationError";
  }
}

try {
  throw new ValidationError("Invalid input!");
} catch (err) {
  console.log(err.name);    // ValidationError
  console.log(err.message); // Invalid input!
}
class AgeError extends Error {
  constructor(message) {
    super(message);
    this.name = "AgeError";
  }
}

function setAge(age) {
  if (age < 0) {
    throw new AgeError("Age cannot be negative.");
  }
  return `Age is set to ${age}`;
}

try {
  console.log(setAge(-5));
} catch (error) {
  if (error instanceof AgeError) {
    console.error("Custom Error:", error.message);
  } else {
    console.error("Other Error:", error.message);
  }
}
class AuthError extends Error {
  constructor(message) {
    super(message);
    this.name = "AuthError";
  }
}

class PermissionError extends Error {
  constructor(message) {
    super(message);
    this.name = "PermissionError";
  }
}

function login(user) {
  if (!user) throw new AuthError("User not found");
  if (!user.isAdmin) throw new PermissionError("Access denied");
  return "Welcome!";
}

try {
  login({ isAdmin: false });
} catch (err) {
  if (err instanceof AuthError) {
    console.log("Login failed:", err.message);
  } else if (err instanceof PermissionError) {
    console.log("Permission issue:", err.message);
  } else {
    console.log("Unknown error:", err.message);
  }
}

🔥 Why Use Custom Errors?

✅ Gives meaningful error types in your application

✅ Allows different error handling for different error types

✅ Helps with cleaner debugging and logging


✅ Best Practices

Practice

Why it matters

Always extend Error

Ensures stack trace and prototype chain are correct

Set this.name manually

So you can identify error types during handling

Use instanceof

To check custom error types when catching


📋 Summary

Term

Meaning

extends Error

Creates a custom error class

super()

Calls the base Error constructor

this.name

Sets your custom error name (recommended)