2012-09-16 41 views
8

我听说有些人在Scala中倾向于(像其他函数式语言一样)不要打断控制流程......而是按照惯例我们返回错误EitherLeft使用Either处理故障 - >堆栈跟踪在哪里?

但是,我们如何从这个异常中得到散记? 现在我回到左边一个简单的Error案例类与代码,消息和原因(Error太)。但是,如果我有一个错误,我无法获得堆栈跟踪。 如果我的应用程序变得复杂,则可能很难找到返回Error的代码块......根本原因很重要。


那么我们在实践中做什么?

我应该返回,而不是自定义Error,在我的Left Java类型ExceptionThrowable? Scala异常处理的最佳实践是什么,而不会丢失重要信息,如堆栈跟踪和原因?

+1

就像一个说明,在即将到来的斯卡拉2.10 [也有尝试](http://blog.richdougherty.com/2012/06/error-handling-with-scalas-try.html)错误处理 –

+0

@ om-nom-nom感谢这似乎非常好! –

回答

11

我建议使用Either[java.lang.Throwable, A](其中Throwable仍然允许您访问堆栈跟踪),并且(通常)使您的自定义错误类型扩展为java.lang.Exception

这是通过Dispatch 0.9使用的做法,例如,其中Either[Throwable, A]用于表示可能出现故障的计算和定制的错误类型是这样的:

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

Scalaz 7Validation.fromTryCatch(a: => T)也返回一个Validation[Throwable, T] ,其中Validation大致相当于Either

+0

我会争辩说,尽管有一些封装异常的例子,但在实践中这是一件很愚蠢的事情。如果你有一些错误编码方案,一个是有道理的;否则只是抛出异常,以便呼叫链中较高的那个可以处理或传递它。 –

+0

@rs_atl:例如,当我尝试将一个字符串解析为一个整数时,我遇到了类似'NumberFormatException'的可能性。抛出异常并使用自定义错误类或包装对我来说似乎比简单的'Either [Throwable,Int]'方法更可怕。 –

+0

@TravisBrown谢谢。返回Left(Throwable)而不是Left(Exception)是否是一种好习惯?因为我们不应该捕捉Throwables。它可能会导致开发人员发现一个OutOfMemory错误,例如没有? –