← Back to TypeScript Course | Chapter 18: Error Handling | Lesson 2 of 5

Custom Error Classes

Custom error classes let applications represent specific failure conditions with meaningful names and properties. They extend the built-in Error class and can be narrowed with instanceof.

Creating a Custom Error

A custom error class extends the built-in Error and usually sets this.name to a specific string, which lets logging and error-reporting tools identify exactly which category of failure occurred at a glance.

Example: Creating a Custom Error

typescript
class NotFoundError extends Error {
  constructor(message: string) {
    super(message);
    this.name = "NotFoundError";
  }
}
try {
  throw new NotFoundError("User not found");
} catch (err) {
  if (err instanceof NotFoundError) console.log(err.name, err.message);
}

Custom Error Properties

Custom errors can carry additional typed properties beyond the standard message — an error code, a resource id, a validation field name — giving catch blocks structured data to act on instead of just parsing a string.

Example: Custom Error Properties

typescript
class ValidationError extends Error {
  constructor(message: string, public field: string) {
    super(message);
    this.name = "ValidationError";
  }
}
try {
  throw new ValidationError("Required", "email");
} catch (err) {
  if (err instanceof ValidationError) console.log(err.field, err.message);
}

Multiple Custom Errors

Different error classes can represent different failure categories — NotFoundError, ValidationError, AuthError — and be caught and handled separately, so each kind of failure gets an appropriately different response.

Example: Multiple Custom Errors

typescript
class NotFoundError extends Error {}
class ValidationError extends Error {}
class AuthError extends Error {}
function handle(err: Error) {
  if (err instanceof NotFoundError) console.log("404");
  else if (err instanceof ValidationError) console.log("400");
  else if (err instanceof AuthError) console.log("401");
}
handle(new ValidationError("bad input"));

Custom Errors in Functions

Functions can throw custom errors while callers use instanceof checks to decide how to respond, turning a generic try/catch into a dispatch table over specific, meaningful failure types.

Example: Custom Errors in Functions

typescript
class NotFoundError extends Error {}
function findUser(id: number) {
  if (id !== 1) throw new NotFoundError("User not found");
  return { id, name: "Ravi" };
}
try {
  findUser(2);
} catch (err) {
  if (err instanceof NotFoundError) console.log("Handled:", err.message);
}

Best Practices for Custom Errors

Reserve custom errors for meaningful application-level failures worth distinguishing, and keep their extra properties focused and strongly typed rather than turning every error into a loosely-typed grab bag.

Example: Best Practices for Custom Errors

typescript
class PaymentError extends Error {
  constructor(message: string, public code: number) {
    super(message);
    this.name = "PaymentError";
  }
}
try {
  throw new PaymentError("Card declined", 402);
} catch (err) {
  if (err instanceof PaymentError) console.log(err.code, err.message);
}
🔒

Chapter Quiz — Complete all 5 topics to unlock

0/5 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.