When "trace" is on, an exceptional occurrence such as a test failure results in a full stack trace being printed. In many cases, the full information from that trace is not useful since much of it is just about sbt's calls to invoke the test (or other user code).
It would be nice to have a way to specify that stack traces should be shown, but only to a certain integer depth. A useful sub-case of this is to show just the top-level message, which for many testing frameworks is enough to identify the failing test and the data that caused the failure.
Comment #1
Posted on Nov 23, 2009 by Quick Panda(No comment was entered for this change.)
Comment #2
Posted on Nov 24, 2009 by Happy Elephantor perhaps instead of an integer stack trace, the output could simply omit the first line that's in sbt code and everything after.
Comment #3
Posted on Nov 24, 2009 by Quick PandaIf anyone wants to write a function (Throwable, Int) => String, I'll integrate it.
If the integer is < 0, include everything. If 0, include up to the first sbt/xsbt line. If > 0, include that many lines. Reliably detecting the first sbt frame seems to involve operating on StackTraceElement, which would mean reimplementing printStackTrace.
Comment #4
Posted on Jan 13, 2010 by Grumpy ElephantI've finally found some time to look at this. A basic version is easy and I have it running.
What would you like to do when the Throwable has a cause? Should its stack trace be included as it would be with printStackTrace (at least part of it)? Should the depth parameter apply to the traces of the cause(s)? Or should the causes be ignored if the depth param is >= 0? Any ideas?
Comment #5
Posted on Jan 13, 2010 by Grumpy ElephantFurther to my last comment, I suggest that if the user sets the depth to < 0, sbt should just use printStackTrace.
This ensures that all of the causes etc are printed in a standard way. The function we are talking about here
should only be used if the users wants to trim the stack trace (ie depth is >= 0).
Comment #6
Posted on Jan 13, 2010 by Quick PandaAgreed on depth < 0. Java doesn't print frames multiple times so I was thinking depth would continue to the cause and just be the total number of lines printed.
Exception 1 element 1 element 2 Caused by: Exception 2 element 1 ... x more
Maybe 0 prints each exception, 1 prints Exception1 + element1, 3 prints through Exception 2? It might turn out to be easier to implement something else though, which would be fine, as long as it make some sense or is useful. Thanks for looking at this.
-Mark
Comment #7
Posted on Jan 13, 2010 by Grumpy ElephantOk, so I went with the simple line-based interpretation for now. A depth > 0 is interpreted as the maximum number of stack elements to print, including those from nested causes. We can see how it goes.
Code is attached, including some simple tests. You will want trimStackTrace() and appendStackTrace() from Main.scala. It could be made a bit more efficient and definitely more functional, but it's probably not worth the effort.
- Main.scala 2.72KB
- User.scala 317
Comment #8
Posted on Jan 13, 2010 by Happy ElephantUsually the causing exception is by far the most important one to me — the details of any further exceptions that result from it are usually much less interesting. So I would strongly suggest interpreting e.g. a depth of 3 as "print 3 lines of every exception in the chain", not "print only 3 lines even if that means the causing exception doesn't get shown at all". The causing exception is the most important — it's exactly what shouldn't be omitted.
Comment #9
Posted on Jan 13, 2010 by Grumpy ElephantThanks for your comment Seth. That would be easy to do and is easy for the user to understand. What do you think, Mark?
Comment #10
Posted on Jan 13, 2010 by Quick PandaSounds good.
Comment #11
Posted on Jan 14, 2010 by Grumpy ElephantOk, here's the new version (User.scala is unchanged). There is one small change in interpretation from my
previous version. The depth now refers to the number of lines to print, not the number of elements to print.
Thus, a depth of 1 just gives you a list of the throwables with no stack elements printed.
- Main.scala 2.57KB
Comment #12
Posted on Jan 14, 2010 by Quick PandaIntegrated into 0.6.10, configured by doing:
trace on (full stack traces) trace nosbt (stack traces up to sbt) trace off (no stack traces) trace (number of frames per exception)
Thanks for the enhancement.
Comment #13
Posted on Jan 14, 2010 by Grumpy ElephantNo problem. Thanks for integrating it so quickly.
Comment #14
Posted on Jan 15, 2010 by Grumpy ElephantI tried this with 0.6.10. The trace command accepts the parameters I expected (except the help message doesn't mention "nosbt". Is that deliberate?) However, the trace setting doesn't seem to affect whether I get a trace or not; I always seem to get one with all elements listed, whatever the trace setting is (even with "trace off"). This is a trace from a failing scalatest test if that matters.
Comment #15
Posted on Jan 15, 2010 by Quick PandaThe nosbt omission was unintentional and I'll fix that.
ScalaTest doesn't currently send sbt the exception but does printStackTrace, so sbt doesn't have a chance to handle it. If you see an announcement about ScalaTest being updated for test-interface 0.3 or later, it should work as expected then.
Comment #16
Posted on Jan 15, 2010 by Grumpy ElephantAh, ok, thanks.
Comment #17
Posted on Jan 16, 2010 by Quick Panda'nosbt' should be in the 'trace' error message in 0.6.11. Thanks.
Comment #18
Posted on Jan 23, 2010 by Grumpy OxThe trace command does not seem to apply to forked tasks. Is that an inherent limitation?
Comment #19
Posted on Jan 24, 2010 by Quick PandaRight, it only affects when exceptions are logged directly. Exceptions in forked processes just get printed without a chance to process the exception directly.
Status: Fixed
Labels:
Type-Enhancement
Priority-Medium