Skip to content

Exception Handling in JavaScript

The general structure of the try...catch block is:

try {
// Code that may throw an error
} catch (error) {
// Code to handle the error
} finally {
// Optional code that runs regardless of success or failure
}
javascript

How to Create Custom Exceptions in JavaScript

Section titled “How to Create Custom Exceptions in JavaScript”

You can create custom exception classes by extending JavaScript’s built-in Error class. This allows you to add custom properties like error codes and additional details, making your error handling more informative and structured.

The following example shows a CustomError class that accepts a message, an error code, and a details object for storing custom data. The class extends Error and uses the super() method to initialize the parent class while adding custom properties.

/**
* Custom error class that extends the built-in `Error` class.
* It includes additional properties such as a custom error code and details.
* This allows for more context when handling errors.
*
* @class
* @extends {Error}
*/
class CustomError extends Error {
/**
* Creates an instance of CustomError.
*
* @param {string} message - The error message.
* @param {string|number} code - A custom error code to help identify the type of error.
* @param {Object} [details] - Optional additional context or details about the error (e.g., a stack trace, data, etc.).
*/
constructor(message, code, details) {
super(message); // Call the parent constructor with the message
this.name = this.constructor.name; // Set the error name to CustomError
this.code = code; // Custom error code
this.details = details; // Additional details or context
// Optional: Ensure the stack trace is correct for this subclass
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
}
}
}
javascript

You can create more specific error classes by extending CustomError. This is useful for handling different error scenarios:

class NotFoundError extends CustomError {
constructor(message, details) {
super(message, 404, details);
}
}
class ValidationError extends CustomError {
constructor(message, details) {
super(message, 400, details);
}
}
javascript

Once you’ve created a custom exception class, you can throw instances of it with specific data:

try {
// Simulate a situation that triggers an error
throw new CustomError("Invalid user input", 400, { field: "username", expected: "non-empty" });
} catch (error) {
if (error instanceof CustomError) {
console.log("CustomError caught!");
console.log(`Message: ${error.message} (Code: ${error.code})`);
console.log("Details:", error.details);
} else {
console.error("An unknown error occurred:", error);
}
}
javascript

The same approach works with specialized error classes like ValidationError and NotFoundError:

try {
// Simulate validation failure
throw new ValidationError("Invalid input data", { field: "email", expectedFormat: "email@domain.com" });
} catch (error) {
if (error instanceof ValidationError) {
console.log("Caught a ValidationError:");
console.log(`Message: ${error.message} (Code: ${error.code})`);
console.log("Details:", error.details);
} else {
console.error("Unknown error occurred:", error);
}
}
javascript

When dealing with multiple error types, use instanceof to handle each one specifically:

function simulateError(errorType) {
switch (errorType) {
case "validation":
throw new ValidationError("Validation failed for username", { field: "username", reason: "empty" });
case "notFound":
throw new NotFoundError("User not found", { resourceType: "User", id: 123 });
default:
throw new CustomError("An unexpected error occurred", 500, { info: "Something went wrong" });
}
}
try {
// Test with "validation" error
simulateError("validation");
} catch (error) {
if (error instanceof ValidationError) {
console.log("Handled ValidationError specifically:");
console.log(`Message: ${error.message} (Code: ${error.code})`);
console.log("Details:", error.details);
} else if (error instanceof NotFoundError) {
console.log("Handled NotFoundError specifically:");
console.log(`Message: ${error.message} (Code: ${error.code})`);
console.log("Details:", error.details);
} else if (error instanceof CustomError) {
console.log("Handled general CustomError:");
console.log(`Message: ${error.message} (Code: ${error.code})`);
console.log("Details:", error.details);
} else {
console.error("Unknown error type:", error);
}
}
javascript