【问题标题】:Better to return None or throw an exception when fetching URL?获取 URL 时最好返回 None 或抛出异常?
【发布时间】:2011-10-16 23:43:20
【问题描述】:

我有一个 Scala 辅助方法,该方法当前尝试获取 URL 并返回带有该网页 HTML 的 Option[String]。

如果有任何异常(格式错误的 url、读取超时等)或者如果有任何问题,它会返回 None。问题是,最好只抛出异常以便调用代码可以记录异常,还是在这种情况下返回 None 更好?

【问题讨论】:

  • 如果它是一个辅助方法,我认为它是私有的。如果它是私人的,那么你就是调用者。如果您是呼叫者,那么您就是知道应该发生什么的所有信息的人,所以随心所欲。否则请参阅 Jean 的回答。

标签: scala exception throw idioms scala-option


【解决方案1】:

创建异常的成本很高,因为必须填充堆栈跟踪。抛出和捕获异常也比正常返回更昂贵。考虑到这一点,您可能会问自己以下问题:

  • 你想强制调用者处理错误吗?如果是这样,不要抛出异常,因为 Scala 没有强制调用者捕获的检查异常机制他们。

  • 如果出现错误,您是否希望包含有关失败原因的详细信息? 如果没有,您可以返回Option[A],其中A 是您的返回类型,然后你要么有Some(validContent) 要么None,没有额外的解释。如果是,您可以返回 Either[E, A] 或 Scalaz Validation[E, A] 之类的内容。所有这些选项都会强制调用者以某种方式解开结果,同时可以随意处理错误E。现在E 应该是什么?

  • 是否要在失败时提供堆栈跟踪?如果是,您可以返回Either[Exception, A]Validation[Exception, A]。如果你真的要例外,你会想要使用Try[A],它的两种可能的情况是Failure(exc: Throwable)Success(value: A)。请注意,您当然会承担创建 throwable 的成本。如果没有,您可以只返回Either[String, A](并且要特别注意这里Right 表示成功还是失败——Left 通常用于错误,Right 用于“正确”值——@987654339 @ 可能更清楚)。如果您想可选地返回堆栈跟踪,您可以使用 Lift 的 Box[A],可以是 Full(validContents)Empty,无需额外说明(与 Option[A] 非常相似) , 或指示一个Failure,它可以存储错误字符串和/或可抛出的(以及更多)。

  • 您是否希望提供多个指示来说明失败的原因?然后返回 Either[Seq[String], A]。如果您经常这样做,您可能想要使用 Scalaz 和 Validation[NonEmptyList[String], A],它提供了一些其他的好东西。查找更多信息或查看these usage examples

【讨论】:

  • 很棒的总结!就个人而言,我大部分时间都使用 Either[String,...],但 Scalaz 的验证似乎更清晰。
【解决方案2】:

一般的经验法则是“如果你能处理异常,就处理它”。所以没有足够的上下文来猜测。您可以使用 tryFetchUrl/fetchUrl 对方法。

【讨论】:

    【解决方案3】:

    我认为在这种情况下,如果记录异常很重要,那么一定要抛出异常(并且可能只返回 String 而不是选项)。否则,您不妨只返回 None。一个警告 - 可能会因为您无法预见的其他原因而出现异常,在这种情况下,编写一个包罗万象的代码可能会很危险。

    您可以做的一件事是类似于 Lift 的Box 系统。 Box 本质上是一个选项,但添加了几个功能:Full 类似于SomeEmpty 类似于None,但 Lift 更进一步,具有Failure,这就像Empty,但有一个原因/消息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-22
      • 2012-06-08
      • 2016-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-30
      • 1970-01-01
      相关资源
      最近更新 更多