【问题标题】:Handling failures with Either -> Where is the stacktrace?使用 Either 处理失败 -> 堆栈跟踪在哪里?
【发布时间】:2012-09-16 19:22:44
【问题描述】:

我从一些人那里听说,在 Scala 中,我们倾向于(像其他函数式语言一样)不破坏控制流......相反,按照惯例,我们在 Either Left 中返回错误。

但是我们如何从那个异常中获取 stracktrace 呢? 现在我在左侧返回一个简单的Error 案例类,其中包含代码、消息和原因(Error 也是)。但是,如果我有错误,我将无法获取堆栈跟踪。 如果我的应用程序变得复杂,可能很难找到返回 Error 的代码块...根本原因是必不可少的。


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

我应该在我的Left 中返回java 类型ExceptionThrowable,而不是自定义Error? 在不丢失堆栈跟踪和原因等重要信息的情况下,Scala 异常处理的最佳做法是什么?

【问题讨论】:

  • 作为一个注释,在即将发布的 Scala 2.10 there is also Try 中进行错误处理
  • @om-nom-nom 谢谢,这看起来真的很好!

标签: java scala exception exception-handling either


【解决方案1】:

我建议使用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

【讨论】:

  • 我认为,尽管有在 Either 中封装异常的例子,但在实践中这样做很愚蠢。如果您有一些错误编码方案,那么 Either 是有意义的;否则只需抛出异常,以便调用链中较高的那些可以处理或传递它。
  • @rs_atl:假设我在尝试将字符串解析为整数时遇到了NumberFormatException 之类的可能性。在我看来,抛出异常和使用自定义错误类或包装器都比简单的 Either[Throwable, Int] 方法更愚蠢。
  • @TravisBrown 谢谢。返回 Left(Throwable) 而不是 Left(Exception) 是一种好习惯吗?因为无论如何我们都不应该捕获 Throwables。例如,它可能会导致开发人员捕获 OutOfMemory 错误?
  • 顺便说一句,Scala 2.10 的 Try 方法是捕获异常和非致命错误,如 stackoverflow。看起来不错
  • @TravisBrown:NumberFormatException 的公平点。但是我使用 Either 作为异常报告机制的问题是它迫使调用者在处理异常或将 Either 向上传递调用链之间进行选择。如果函数的目的足够单一,那么在大多数情况下,简单地返回一个选项或抛出异常上线似乎是合乎逻辑的。投反对票...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-29
  • 2015-07-30
相关资源
最近更新 更多