I a while ago i used to use Verror from joyent to not lose the stacktrace when rethrowing, I have just done a test with node v12 without Verror and stack trace seems to be persisted without the use of error.
I then was looking at the use of Error.captureStackTrace, it states to use this in your errors so that the Error is not added to the stack.
I don't what i am doing wrong but with or without Error.captureStackTrace - the stack trace is the same..
I would like to know the current status of the use of the captureStackTrace as i see no difference :-) and also the use of VError that doesn't seem to be needed anymore.
In the documentation it states that the .stack isn't available without calling the captureStackTrace but I see it available each time, with or without the captureStackTrace
here is an example of 2 x errors
class MyErrorOne extends Error {
constructor(message) {
super(message);
Error.captureStackTrace(this, this.constructor);
}
}
class MyErrorTwo extends Error {
constructor(message) {
super(message);
Error.captureStackTrace(this, this.constructor);
}
}
I tried them by commenting out the captureStackTrace in EACH error and the stacktrace is the same.
Can anyone help ?
Here is my code to test calling the errors
const DoOne = () => {
try {
console.log("executing do one");
DoTwo();
} catch (error) {
console.log("error in DoOne", error);
console.log("here is the stack ", error.stack);
throw new MyErrorOne("threw error from doone in myerrorone");
// throw error;
}
};
const DoTwo = () => {
try {
console.log("executing do two");
throw new MyErrorTwo("threw error from dotwo in myerrortwo");
} catch (error) {
console.log("error in DoTwo", error);
throw error;
}
};
DoOne();
When calling Error.captureStackTrace(obj[, fun])
a formatted call stack is attached to obj
including the line/frame where captureStackTrace
was called.
When specifying fun
all frames above and including fun
are removed.
Note: In sample outputs I have removed anything below call to fun1
to minimize clutter.
const fun1 = () => { fun2(); };
const fun2 = () => { fun3(); };
const fun3 = () => { log_stack(); };
function log_stack() {
let err = {};
Error.captureStackTrace(err);
console.log(err.stack);
}
fun1();
This yields:
Error
at log_stack (/path/to/example.js:6:8)
at fun3 (/path/to/example.js:3:22)
at fun2 (/path/to/example.js:2:22)
at fun1 (/path/to/example.js:1:22)
Now, if we add log_stack
as the function option to captureStackTrace
:
Error.captureStackTrace(err, log_stack);
It yields:
Error
at fun3 (/path/to/example.js:3:22)
at fun2 (/path/to/example.js:2:22)
at fun1 (/path/to/example.js:1:22)
The log_stack
frame is not there anymore.
Adding fun3
to the captureStackTrace
:
Error.captureStackTrace(err, fun3);
It yields:
Error
at fun2 (/path/to/example.js:2:22)
at fun1 (/path/to/example.js:1:22)
Etc.
In your case, if you change:
Error.captureStackTrace(this, this.constructor);
to:
Error.captureStackTrace(this);
You will see that you get an additional line with the new MyError...
:
error in DoTwo MyErrorTwo: threw error from dotwo in myerrortwo
at new MyErrorTwo (/path/to/testerrorclass.js:10:9) <<== Not removed anymore.
I'm not sure, but it seems that Error.captureStackTrace
is intended to be used when constructing Error object without extending the Error
class (see also the example provided in the Node docs.
I'm guessing that when you're extending the Error
class, capturing the stack trace is already done by the Error constructor.
I've tested your code and remove the extending of Error and indeed if you don't call captureStackTrace
you will not get a stack trace on your error objects.
I'm not sure what would be the use case of throwing Errors that are not extending the Error class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With