tapjs/stack-utils

Support promise long stack traces

Closed this issue · 9 comments

Currently this:

Error: e
    at null._onTimeout (/Users/jamestalmage/WebstormProjects/stack-utils/foo.js:27:11)
    at Timer.listOnTimeout (timers.js:119:15)
From previous event:
    at /Users/jamestalmage/WebstormProjects/stack-utils/foo.js:25:9
    at processImmediate [as _immediateCallback] (timers.js:367:17)
From previous event:
    at Object.<anonymous> (/Users/jamestalmage/WebstormProjects/stack-utils/foo.js:24:3)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3

becomes this

null._onTimeout (foo.js:27:11)
From previous event:
foo.js:25:9
From previous event:
Object.<anonymous> (foo.js:24:3)
node.js:814:3

Pretty good, but it It would be better if the cleaned stack trace kept some form of indentation between the From previous event lines.

I am not sure the best way to detect this, just look for From previous event? This example is bluebird, but I know q and others support the same idea, but I'm not sure how they format it.

Would it just be better to look for unindented separator lines? That may cover a wider range of implementations, but are normal stack trace lines always guaranteed to be indented?

// @sindresorhus @isaacs

Look for lines not starting with at?

Yeah, seems like just preserving lines not matching /^at / would be good, and if any such lines are found, indent all the others, so that the From previous event: line is out-dented?

Or just indent any lines that come after the From previous line so you get this?

null._onTimeout (foo.js:27:11)
From previous event:
    foo.js:25:9
From previous event:
    Object.<anonymous> (foo.js:24:3)
    node.js:814:3

The benefit of doing it the /^at / way is that it would support other stack modifying things like e.g. https://github.com/mdlavin/nested-error-stacks

I think the suggestion is just not to start the stack trace with outdented lines (clean currently strips the error message off the first line, so your first line would usually be outdented by default):

A:

null._onTimeout (foo.js:27:11)
From previous event:
    foo.js:25:9
From previous event:
    Object.<anonymous> (foo.js:24:3)
    node.js:814:3

vs B:

    null._onTimeout (foo.js:27:11)
From previous event:
    foo.js:25:9
From previous event:
    Object.<anonymous> (foo.js:24:3)
    node.js:814:3

I much prefer A. Especially since it looks so much nicer when dumped to yaml. Actually, any indentation will make TAP's yaml output kinda ugly, because | and > are not possible if lines start or end with spaces.

Oh! i was wrong. It's only if the whole string starts or ends with whitespace that folding isn't allowed.

> var y = require('js-yaml')
undefined
> var a = 'null._onTimeout (foo.js:27:11)\nFrom previous event:\n  foo.js:25:9\n'
undefined
> var b = '    ' + a
undefined
> console.log(y.safeDump({A: a, B: b}))
A: |
  null._onTimeout (foo.js:27:11)
  From previous event:
    foo.js:25:9
B: "    null._onTimeout (foo.js:27:11)\nFrom previous event:\n  foo.js:25:9\n"
undefined

So, with that, strong preference for A rather than B.

strong preference for A

👍 My only concern is for situations where someone isn't converting to yaml and actually wants to show the error message (I am thinking this may be the case for AVA's default non-tap reporter). I'm just going to implement A for now, and punt on making B a configurable choice until we've actually demonstrated a need for it.

Next question, what to do when every at line under a give From previous ... line is considered internal (and would be deleted from the stack trace). With long stack traces turned on now, most AVA test failures I see have one or two completely useless sections at the end.

I think it is pretty safe to delete empty sections from the the end of the stack. But what if it's in the middle? Is that even a real possibility?