UserError is a base class that makes JavaScript errors a lot more useful. It gives you:
- An
Error
subclass that actually works - Support for checking error types using
instanceof
- A correct
name
property on error objects - Cleaner stack traces
import UserError from "https://deno.land/x/user_error/mod.ts";
class MyError extends UserError {
constructor(message: string) {
super(message);
}
}
To see the problems UserError solves for you, let's try to subclass Error
directly and see what happens.
class MyError extends Error {
constructor(message: string) {
super(message);
}
}
const boom = (): never => {
throw new MyError("boom!");
};
try {
boom();
} catch (error) {
error instanceof Error; // true (correct)
error instanceof MyError; // false (wrong, should be true)
error.name; // Error (wrong, should be MyError)
}
In this example, subclassing Error
is useless;
we can't really differentiate an instance of MyError
from any other Error
in the system.
This inability to subclass Error
has led to a number of other workarounds,
most often adding some kind of code
property to error objects,
so you end up doing stuff like this:
if (error.code === SomeErrorCode)
// ...
In addition to this problem, errors created in this way include extra noise in their stack trace:
Error: boom! << should be "MyError: boom!"
at MyError.Error (native) << noise
at new MyError (test.js:3:7) << noise
at boom (test.js:10:9)
at Object.<anonymous> (test.js:14:3)
UserError aims to fix these problems. Now, when we run the example it looks like this:
import UserError from "https://deno.land/x/user_error/mod.ts";
class MyError extends UserError {
constructor(message: string) {
super(message);
}
}
const boom = (): never => {
throw new MyError("boom!");
};
try {
boom();
} catch (error) {
error instanceof Error; // true
error instanceof MyError; // true
error.name; // MyError
}
Since both instanceof
work and the name
property is setup correctly, we can do either
if (error instanceof MyError)
// ...
or
if (error.name === 'MyError')
// ...
instead of duck-typing with a custom property. Additionally, the stack trace doesn't contain unnecessary entries:
MyError: boom!
at boom (test.js:10:9)
at Object.<anonymous> (test.js:14:3)
user_error is released under the MIT License. See the bundled LICENSE file for details.
Heavily inspired by mjackson/usererror.