10

I heard from some people that in Scala we tend (like other functional languages) to not break the control flow... Instead by convention we return the error in an Either Left.

But how do we get the stracktrace from that exception? For now i return in the Left a simple Error case class with a code, message and cause (Error too). But if i have an error, i can't get the stacktrace. If my application become complexe it may be hard to find the code block that returned that Error... The root cause is essential.


So what do we do in practice?

Should i return, instead of a custom Error, the java type Exception or Throwable in my Left? What's the best practice for Scala exception handling without loosing important informations such as the stacktrace and the cause?

Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419

1 Answers1

12

I'd suggest using Either[java.lang.Throwable, A] (where Throwable still gives you access to the stack trace), and (in general) making your custom error types extend java.lang.Exception.

This is the practice used by Dispatch 0.9, for example, where Either[Throwable, A] is used to represent computations that may fail, and the custom error types look like this:

case class StatusCode(code: Int)
  extends Exception("Unexpected response status: %d".format(code))

Scalaz 7's Validation.fromTryCatch(a: => T) also returns a Validation[Throwable, T], where Validation is roughly equivalent to Either.

Travis Brown
  • 138,631
  • 12
  • 375
  • 680
  • I would argue that although there are examples of encapsulating exceptions in an Either, this is a silly thing to do in practice. If you have some error coding scheme, an Either makes sense; otherwise just throw the exception so those higher up in the call chain can either handle or pass it through. – rs_atl Sep 16 '12 at 20:03
  • @rs_atl: Say I'm stuck with the possibility of something like a `NumberFormatException` when trying to parse a string into an integer, for example. Both throwing the exception and using a custom error class or wrapper seem sillier to me than the simple `Either[Throwable, Int]` approach. – Travis Brown Sep 16 '12 at 20:09
  • @TravisBrown thanks. Is it a good practice to return a Left(Throwable) instead of a Left(Exception)? Since we are not supposed to catch Throwables anyway. It may lead a developper to catch an OutOfMemory error for exemple no? – Sebastien Lorber Sep 17 '12 at 08:14
  • Btw the approach of Scala 2.10's Try is to catch Exceptions and non-fatal Errors like stackoverflow. Seems nice – Sebastien Lorber Sep 17 '12 at 08:29
  • 2
    @TravisBrown: Fair point on the NumberFormatException. But the issue I have with using Either as an exception reporting mechanism is that it forces the caller to choose between dealing with an exception or passing an Either up the call chain. If functions are sufficiently singular in their purpose, simply returning an Option or throwing the exception upline seem logical in *most* cases. Bring on the downvotes... – rs_atl Sep 17 '12 at 14:23
  • That's the distinction to make - whether something is truly "exceptional" and should go all the way up the call chain or whether it should be handled locally. If it's local then using one of the functional approaches is a great way to go. – sourcedelica Oct 22 '12 at 17:48