Custom Errors
Overview
In large enterprise applications, relying solely on the generic Error object makes debugging difficult. By creating Custom Error classes, you can attach specific metadata (like HTTP status codes or database IDs) to the error.
You create a Custom Error by extending the built-in Error class.
Syntax
// Extend the native Error class
class ValidationError extends Error {
constructor(message, field) {
// Call the parent constructor with the message
super(message);
// Attach custom metadata!
this.name = "ValidationError";
this.field = field;
}
}try {
const email = "invalid";
if (!email.includes("@")) {
throw new ValidationError("Invalid email format", "emailInput");
}
} catch (err) {
// We can use 'instanceof' to handle different errors differently!
if (err instanceof ValidationError) {
console.log(`Highlighting the UI field: ${err.field}`);
} else {
console.log("Generic server crash!");
}
}Common Pitfalls
Forgetting to call
super(message)inside the constructor of the custom error. If you omitsuper(), the underlying nativeErrorlogic (including generating the stack trace) will not execute, breaking the error entirely.
Interview Questions
How do you distinguish between multiple types of errors in a single catch block?
By using the instanceof operator. You can write conditional logic like if (err instanceof ValidationError) vs if (err instanceof DatabaseError) to handle them gracefully.
Real-World Example
Creating an HttpError class for API calls that includes the exact HTTP status code (404, 500) so the frontend knows whether to show 'Not Found' or 'Server Down'.
class HttpError extends Error {
constructor(status, msg) {
super(msg);
this.status = status;
}
}Check Your Knowledge
Test your understanding of Custom Errors with these quick questions.