loqatevars
Version:
Locate JavaScript files with 'const' or 'process.env' usage in LLM-generated codebases
100 lines (95 loc) • 3.86 kB
JavaScript
/**
* @file This file defines a hierarchy of custom error classes for the application.
* By creating a structured error hierarchy, we can handle different types of errors
* more effectively and provide more meaningful feedback to the user.
*
* The error classes are designed to distinguish between operational errors (expected issues)
* and programmer errors (bugs), which is a best practice for robust error handling.
*/
/**
* `AppError` is the base class for all custom errors in the application.
* It extends the built-in `Error` class and adds support for a `code` property,
* which allows for more specific error handling based on a unique identifier.
*
* This class serves as the foundation for creating more specialized error types,
* such as `OperationalError` and `ProgrammerError`.
*
* @class AppError
* @extends {Error}
*/
class AppError extends Error {
/**
* Creates an instance of AppError.
* @param {string} message - A human-readable description of the error.
* @param {string} code - A unique, machine-readable code for the error (e.g., 'INVALID_DIRECTORY').
* @memberof AppError
*/
constructor(message, code) {
super(message);
// this.constructor.name ensures that the error name is always the name of the class
this.name = this.constructor.name;
// The 'code' property provides a stable, machine-readable identifier for the error.
this.code = code;
// `Error.captureStackTrace` creates a .stack property on `this` instance, which is a string
// representing the point in the code at which the error was instantiated.
Error.captureStackTrace(this, this.constructor);
}
}
/**
* `OperationalError` is used for runtime errors that are expected to occur under
* certain conditions, such as invalid user input or external service failures.
* These are not bugs in the code but rather predictable issues that need to be handled gracefully.
*
* The `isOperational` flag is a key property that allows us to distinguish these errors
* from programmer errors and handle them differently (e.g., by showing a friendly message to the user).
*
* @class OperationalError
* @extends {AppError}
*/
class OperationalError extends AppError {
/**
* Creates an instance of OperationalError.
* @param {string} message - A human-readable description of the error.
* @param {string} code - A unique, machine-readable code for the error.
* @memberof OperationalError
*/
constructor(message, code) {
super(message, code);
// This flag indicates that the error is an operational error, which can be useful
// for centralized error handling logic.
this.isOperational = true;
}
}
/**
* `ProgrammerError` is used for bugs and other unexpected issues in the code.
* These are errors that should ideally never happen and indicate a flaw in the program's logic.
*
* The `isProgrammerError` flag helps in identifying these errors so that they can be
* logged with more detail (e.g., with a full stack trace) for debugging purposes.
*
* @class ProgrammerError
* @extends {AppError}
*/
class ProgrammerError extends AppError {
/**
* Creates an instance of ProgrammerError.
* @param {string} message - A human-readable description of the error.
* @param {string} code - A unique, machine-readable code for the error.
* @memberof ProgrammerError
*/
constructor(message, code) {
super(message, code);
// This flag indicates that the error is a programmer error, which helps in
// distinguishing it from operational errors.
this.isProgrammerError = true;
}
}
/**
* The custom error classes are exported so that they can be used throughout the application.
* This allows for consistent and structured error handling across different modules.
*/
module.exports = {
AppError,
OperationalError,
ProgrammerError
};