Javascript - can you throw an object in an Error?
For anyone using typescript, you can extend the ErrorConstructor
interface and add your own constructor that accepts an object like this:
class MyError extends Error {
readonly id: number
// base constructor only accepts string message as an argument
// we extend it here to accept an object, allowing us to pass other data
constructor({ id, name, message }) {
super(message)
this.name = name // this property is defined in parent
this.id = id
}
}
Usage
function doSomething() {
if (somethingWentWrong) {
throw new MyError({
id: 502,
name: "throttle_violation",
message: "Violation of backoff parameter",
});
}
}
try {
doSomething()
} catch (err) {
if (err instanceof MyError) {
console.log("error id: " + err.id);
console.log("error name: " + err.name);
console.log("error message: " + err.message);
alert(err.property); // name
} else {
// ...
}
}
You could try converting the object to a JSON string and then parsing the error message into a JSON object in the catch statement:
try {
throw Error(JSON.stringify({foo: 'bar'}));
} catch (err) {
console.log(JSON.parse(err.message).foo);
}
Using JSON.stringify()
and JSON.parse()
can be a pain and isn't necessary even. I'd suggest creating your own property for the Error
object, rather than passing the object to the message
parameter, which only accepts a string.
try {
let error = new Error();
Object.assign(error, { foo: 'bar' });
throw error;
} catch (err) {
console.log(err.foo);
}
You can throw your own object, and associate an Error instance with it:
try {
// ...
throw {
foo: "bar",
error: new Error()
};
The throw
statement is not picky, but the Error()
constructor is. Of course, if you throw something that's not an Error, it's only useful if the catching environment expects it to be whatever you throw.
Having the Error object as part of your custom thrown value is useful because a constructed Error instance has (in supporting browsers, which currently seems to be essentially all of them) an associated stack trace.