-
-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Append the cause() stacks to the main stack trace #2381
Conversation
Some Errors support a cause() method that when called returns the error that caused it. Examples are VError, https://github.com/davepacheco/node-verror, and restify v2.0, https://github.com/mcavage/node-restify. The cause() is useful when errors are wrapped using something like VError to preserve the full stack traces by appending the stack traces of the cause() to that of the original error. This is something that eg. Bunyan does https://github.com/trentm/node-bunyan/blob/cbfaa9a7bd86c658dbb8333c894191d23b65be33/lib/bunyan.js#L1111 and this method is inspired by its implementation. Bunyan in turn was inspired by extsprintf: https://github.com/davepacheco/node-extsprintf/blob/accc9f2774189a416f294546ed03b626eec3f80c/lib/extsprintf.js#L165
The noted failure here seems to be unrelated to my PR, seems to be Travis tests that are failing on Node 6.x for some unknown reason |
@voxpelli thanks. restarted the build; looks like it was a network fart |
Can you show an example of this? Also, does the behavior differ when using |
@boneskull If I run this code (just for the sake of showing the output – in reality the errors would be thrown from different places of course): throw new VError(new VError(new Error('First one'), 'Second one'), 'Third one'); Then this will be the output when running Mocha normally:
I haven't checked the |
@boneskull I now added the
And a full trace looks like:
I can squash the commits before merge if you want – just wanted my changes to be clear to you. |
*/ | ||
|
||
exports.getFullErrorStack = function(err, message) { | ||
var ret = err.stack || message || ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we cannot expect err
to be defined, nor can we expect it to be non-null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@boneskull Generally I would agree, but since the lines above and below where getFullErrorStack()
gets called already accesses err.message
, err.inspect
, err.actual
etc. I think we can safely assume that at this stage the err
is defined and is a non-null
value, else that code would be broken as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, must be that we won't add a non-object error to the list. looking into that.
I hadn't noticed err.inspect
here, which sets a precedent for this PR anyway.
@voxpelli Thanks. After reading the material and code you referenced, I'm not too terribly enthusiastic about adding this:
I may be able to suggest a decent workaround. Are you dealing mainly with uncaught errors, or are these failing assertions? Completely subjective opinion: if I found myself suggesting a similar PR, I'd have to question the rationale to wrap Would appreciate another maintainer's take. cc @mochajs/core |
@boneskull Thanks for getting back! Following up on your points:
About interoperability: In async code you have no possibility of a full stack trace, but if you wrap your errors and have each step of the async chain add its own context to the error, with the previous error as its In async code when eg. getting an error like I would be open to look into alternative ways to explore |
there's some other stuff in the works about assertion / mocha interop. the gist of it is that adding support for random properties is not something we want to do; instead assertion libs should have a single place to supply freeform data. this is also very old and the CLA hasn't been signed. |
Some
Error
:s support acause()
method that when called returns the error that caused it. Examples are VError, https://github.com/davepacheco/node-verror, and restify v2.0, https://github.com/mcavage/node-restify.The
cause()
is useful when errors are wrapped by using something likeVError
as one can then preserve the full stack traces by appending the stack traces of thecause()
to that of the original error.This is something that eg. Bunyan does https://github.com/trentm/node-bunyan/blob/cbfaa9a7bd86c658dbb8333c894191d23b65be33/lib/bunyan.js#L1111 and this method is inspired by its implementation.
Bunyan in turn was inspired by extsprintf: https://github.com/davepacheco/node-extsprintf/blob/accc9f2774189a416f294546ed03b626eec3f80c/lib/extsprintf.js#L165
Currently when someone uses eg.
VError
to wrap errors (something suggested in eg. this article from Joyent) the stack traces from Mocha can be fairly useless and it won't point on the actual cause of the issue but just at the last point that wraps it. This would fix that.