-
Couldn't load subscription status.
- Fork 81
Description
Current behaviour:
logErrorCause(message: => String, cause: => Cause[Any]) only logs the last exception message and stack trace in the exception chain.
Desired behaviour:
logErrorCause(message: => String, cause: => Cause[Any]) should log the last exception message with stack trace, including all nested/suppressed/chained exceptions with their stack traces
Example
comment out one of the .catchAllxxx below to run
object Main extends ZIOAppDefault {
case class FirstException(message: String) extends Exception(message)
case class SecondException(message: String, cause: Throwable) extends Exception(message, cause)
case class ThirdException(message: String, cause: Throwable) extends Exception(message, cause)
val triggerException = ZIO.fail(FirstException("First Exception message"))
.mapError(err => SecondException("Second exception message", err))
.mapError(err => ThirdException("Third exception message", err))
override def run: ZIO[Any with ZIOAppArgs with Scope, Any, Any] = {
triggerException
.catchAll(err => ZIO.succeed(err.printStackTrace()))
.catchAllCause(err => ZIO.logErrorCause("log with ZIO Cause", err))
.catchAllTrace {
case (ex, trace) => ZIO.logErrorCause("log with ZIO Cause and trace", Cause.die(ex, trace))
}
.exitCode
}
}Example explanation
.catchAll(err => ZIO.succeed(err.printStackTrace())) will print the "raw" stack trace, including nested exceptions. We want this, but then with the ZIO trace, not the "raw" trace:
Main$ThirdException: Third exception message
at Main$.$anonfun$triggerException$3(Main.scala:15)
at zio.Cause.$anonfun$map$1(Cause.scala:349)
at zio.Cause.$anonfun$flatMap$2(Cause.scala:155)
at zio.Cause$$anon$1.failCase(Cause.scala:178)
...
at zio.internal.FiberRuntime.runLoop(FiberRuntime.scala:889)
...
at zio.internal.FiberRuntime.run(FiberRuntime.scala:140)
at zio.internal.ZScheduler$$anon$3.run(ZScheduler.scala:424)
Caused by: Main$SecondException: Second exception message
at Main$.$anonfun$triggerException$2(Main.scala:14)
... 28 more
Caused by: Main$FirstException: First Exception
at Main$.$anonfun$triggerException$1(Main.scala:13)
at zio.ZIO$.$anonfun$fail$1(ZIO.scala:3021)
at zio.ZIO$.$anonfun$failCause$1(ZIO.scala:3027)
at zio.internal.FiberRuntime.runLoop(FiberRuntime.scala:986)
... 16 more
.catchAllCause(err => ZIO.logErrorCause("log with ZIO Cause", err)) will print only the last exception ("Third exception message") in the chain. Here we would expect also the nested exceptions, but this is not the case:
imestamp=2022-11-19T19:22:38.187461482Z level=ERROR thread=#zio-fiber-6 message="log with ZIO Cause" cause="Exception in thread "zio-fiber-6" Main$ThirdException: Main$ThirdException: Third exception message
at <empty>.Main.triggerException(Main.scala:13)
at <empty>.Main.triggerException(Main.scala:14)
at <empty>.Main.triggerException(Main.scala:15)
at <empty>.Main.run(Main.scala:20)
at <empty>.Main.run(Main.scala:24)" location=<empty>.Main.run file=Main.scala line=20
catchAllTrace { case (ex, trace) => ZIO.logErrorCause("log with ZIO Cause and trace", Cause.die(ex, trace)) } does print the last exception, and all nested exceptions.
at Main$.$anonfun$triggerException$3(Main.scala:15)
at <empty>.Main.triggerException(Main.scala:13)
at <empty>.Main.triggerException(Main.scala:14)
at <empty>.Main.triggerException(Main.scala:15)
at <empty>.Main.run(Main.scala:21)
at <empty>.Main.run(Main.scala:24)
Suppressed: Main$SecondException: Second exception message
at Main$.$anonfun$triggerException$2(Main.scala:14)
Suppressed: Main$FirstException: First Exception
at Main$.$anonfun$triggerException$1(Main.scala:13)" location=<empty>.Main.run file=Main.scala line=22