The BaseError is a robust and flexible base class for creating structured application errors. It provides a consistent error interface with support for predefined error identifiers, message templating, error cause chaining, and contextual details.
You can install BaseError via npm:
npm install baseerrorTo use BaseError in your JavaScript application, first import it:
import BaseError from 'base-error-class';const BaseError = require('base-error-class');The BaseError is designed to be extended by domain-specific error classes.
Subclasses can define a static MESSAGES map containing error identifiers
and message templates.
import BaseError from 'base-error-class';
class ValidationError extends BaseError {
static MESSAGES = new Map([
['INVALID_FIELD', 'The field "{field}" is required or invalid.'],
['OUT_OF_RANGE', 'Value {value} must be between {min} and {max}.'],
]);
}
try {
throw new ValidationError('INVALID_FIELD', {
values: {
field: 'email',
},
details: {
attempted: '',
},
});
} catch (error) {
// ValidationError
console.log(error.name);
// INVALID_FIELD
console.log(error.code);
// The field "email" is required or invalid.
console.log(error.message);
// { attempted: '' }
console.log(error.details);
}For a better development experience, you can document your error identifiers with JSDoc. This allows editors such as Visual Studio Code to provide IntelliSense suggestions for predefined error identifiers while still allowing custom error messages.
For example:
import BaseError from 'base-error-class';
/**
* @template {string} T
* @typedef {T | (string & {})} LiteralUnion
*/
/**
* Identifies a predefined validation error or allows a custom error message.
*
* @typedef {LiteralUnion<
* 'INVALID_FIELD' |
* 'OUT_OF_RANGE'
* >} ValidationErrorIdentifier
*/
class ValidationError extends BaseError {
static MESSAGES = new Map([
['INVALID_FIELD', 'The field "{field}" is required or invalid.'],
['OUT_OF_RANGE', 'Value {value} must be between {min} and {max}.'],
]);
}Creates a new BaseError instance.
BaseError is intended to be extended by application-specific error classes.
| Name | Type | Description |
|---|---|---|
identifier |
string |
A predefined error identifier from MESSAGES, or a custom error message. |
options |
object |
Optional configuration for the error instance. |
| Property | Type | Description |
|---|---|---|
values |
Record<string, unknown> |
Values used to replace {key} placeholders in a predefined message template. |
details |
unknown |
Additional contextual information associated with the error. |
cause |
Error |
The original error that caused this error. |
When identifier exists in the subclass's MESSAGES map, the corresponding
message template is resolved and the identifier is assigned to error.code.
const error = new ValidationError('INVALID_FIELD', {
values: {
field: 'email',
},
});
// INVALID_FIELD
console.log(error.code);
// The field "email" is required or invalid.
console.log(error.message);If the identifier is not defined in MESSAGES, it is treated as a custom
error message and no code property is defined.
const error = new ValidationError('Something went wrong');
// Something went wrong
console.log(error.message);
// undefined
console.log(error.code);Message templates can contain {key} placeholders.
class ValidationError extends BaseError {
static MESSAGES = new Map([
['INVALID_RANGE', '{field} must be between {min} and {max}.'],
]);
}
const error = new ValidationError('INVALID_RANGE', {
values: {
field: 'age',
min: 18,
max: 65,
},
});
// age must be between 18 and 65.
console.log(error.message);If a placeholder does not have a corresponding value, it remains unchanged.
const error = new ValidationError('INVALID_RANGE', {
values: {
field: 'age',
},
});
// age must be between {min} and {max}.
console.log(error.message);Each subclass can define its own MESSAGES map.
class DatabaseError extends BaseError {
static MESSAGES = new Map([
[
'CONNECTION_FAILED',
'Could not connect to database at {host}:{port}.',
],
]);
}Message catalogs belong to the subclass that defines them.
An original error can be preserved using the cause option.
const originalError = new Error('ECONNREFUSED');
const databaseError = new DatabaseError('CONNECTION_FAILED', {
values: {
host: 'localhost',
port: 5432,
},
cause: originalError,
});
// true
console.log(databaseError.cause === originalError);Additional contextual information can be attached using details.
const error = new ValidationError('INVALID_FIELD', {
values: {
field: 'email',
},
details: {
value: 'invalid@example',
},
});
// { value: 'invalid@example' }
console.log(error.details);If you encounter any bugs or issues with BaseError, please open an issue on the GitHub repository. Pull requests are also welcome!
The BaseError class is released under the MIT License.