-
Notifications
You must be signed in to change notification settings - Fork 529
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
Add printStackTrace to Console #1897
Conversation
"printStackTrace to the standard error output" in real { | ||
val e = new Throwable("error!") | ||
|
||
val stackTraceString = |
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.
I'm not sure if we can reliably test this that way: I suppose the representation of a stack trace on the JVM could vary between versions... maybe it's a good idea to keep it while it works, and remove if there are any issues in the future? Or should we just drop it now?
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.
I guess we'll first find out whether it breaks between JDK 8 and 11.
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.
IMO, I think it's fine to just check that the custom message that we do control is present on the err
stream.
uh oh.
😢 A workaround I see would be manually printing in the trait (calling |
Yeah I think the only way we can introduce this is by giving it a default implementation. Something like this might work: def printStackTrace(t: Throwable): F[Unit] = {
val bos = new ByteArrayOutputStream()
val ps = new PrintStream(bos)
t.printStackTrace(ps)
errorln(bos.toString)
} A real question though is whether or not this is entirely safe. I think that, in nearly all cases, |
The default implementation is impure because exceptions are mutable: scala> import java.io._
import java.io._
scala> val oops = new Exception("oops")
val oops: Exception = java.lang.Exception: oops
scala> val sw0 = new StringWriter
val sw0: java.io.StringWriter =
scala> oops.printStackTrace(new PrintWriter(sw0))
scala> oops.addSuppressed(new Exception("lulz"))
scala> val sw1 = new StringWriter
val sw1: java.io.StringWriter =
scala> oops.printStackTrace(new PrintWriter(sw1))
scala> sw0.toString == sw1.toString
val res8: Boolean = false Adding suppressed exceptions is already controversial in our corner of the JVM. Printing the trace before suppressing the exception would be weird. We're not returning a String of the trace. It's impure, but only pedantically so. |
Ugggghhhhh. Okay, @rossabaker, you have a lot more knowledge of horrible things that one can do with exceptions than I do (my heart is still pure!)… Is there a sane default we can throw on here? |
I think the proposed default is fine. It matters when you:
It's impure and that sucks, but there are four stacked reasons not to worry. Scaladoc that "pure only if |
In the interest of trying to resolve this issue, I pushed out a couple of commits. The idea is to copy all of the details from the original throwable to a throwable controlled by the method. The only difference is that the type of the Throwable (the class) is Do we think this is acceptable? On the other hand, we get a bit more safety with regards to mutation. @rossabaker @djspiewak @kubukoz Interested to hear your thoughts. Thanks. |
I managed to work around the changed type of the Throwable using some horrible hacking. |
I'll give it a closer look later today 👀 |
actually no, I did it now.
@vasilmkd what's the purpose of this? Handling the purity problem? If so, I'd just go with the simplest thing that works (Daniel's idea here #1897 (comment)) and add the note about possible impurity |
The idea was to not rely on the |
I don't know if there are ever overrides to This is quite clever, but I'm worried about unintended consequences when the flaws in the simpler method are both rare and easy to accept. |
I agree, the risk is not worth it ultimately. I was having too much fun yesterday. |
92c3cf4
to
e41ade1
Compare
Closes #1895.