Custom Errors in JavaScript and when to use them?
They're more useful than you think.
Table of contents
Introduction
I recently came across custom errors in JavaScript. I was surprised I hadn't seen them before. They can be extremely useful when building larger systems and wanting to provide a good user experience.
How to
You create a class that extends the built-in Error
class. This custom class can have additional properties or methods as needed.
class MyCustomError extends Error {
constructor(message) {
super(message);
this.name = 'MyCustomError';
// Custom logic or additional properties
}
}
When are they useful
From my experience, custom error classes are useful in two situations:
Provide the user with a specific error message.
Be specific when logging the error.
- Logging here refers to observability.
Example
Here we have a quick example with DatabaseError
. It has both the name and operation. Let's say, for instance, you have a type-safe logging library with different names and operations.
You could do something like this for database errors.
Other types of errors would definitely have the name, but maybe not the operation. I guess it depends on the context.
It's nice because of how specific we can be when logging or returning error messages back to the user.
class DatabaseError extends Error {
constructor(message, operation) {
super(message);
this.name = 'DatabaseError';
this.operation = operation;
}
}
// Example usage
try {
// Simulating a database operation failure
throw new DatabaseError('Failed to execute SQL query', 'query');
} catch (error) {
if (error instanceof DatabaseError) {
// Using the external logging library
loggingLibrary.log({
level: 'error',
message: error.message,
errorName: error.name,
operation: error.operation,
timestamp: new Date().toISOString(),
stack: error.stack
});
} else {
// Handle other types of errors
}
}