简体   繁体   English

scalaz:如何在验证中处理不同的错误类型?

[英]scalaz: how to handle different error types in a Validation?

If I have multiple operations that return a Validation[E, _] of something with a fixed error type I can use them in a for-comprehension. 如果我有多个操作返回具有固定错误类型的事物的Validation[E, _] ,我可以在for-comprehension中使用它们。 For example: 例如:

val things: Validation[E, (Int, Double)] = for {
  i <- getValidationOfInt
  d <- getValidationOfDouble
} yield (i, d)

What about if the error types are different? 如果错误类型不同怎么办? Suppose I read from HTTP and want to convert the string response into an Int . 假设我从HTTP读取并希望将字符串响应转换为Int

import scalaz._; import Scalaz._

object ValidationMixing {
  class HttpError

  def getFromHttp: Validation[HttpError, String] = ???
  def parseInt(json: String): Validation[Throwable, Int] =
    Validation.fromTryCatchNonFatal(Integer.parseInt(json))

  val intParsedFromHttp: Validation[Any, Int] = for {
    s <- getFromHttp
    i <- parseInt(s)
  } yield i
}

This compiles, but only because the error type of the Validation is Any , being a supertype of Throwable and HttpError . 这是编译,但只是因为Validation的错误类型是Any ,是ThrowableHttpError的超类型。 This isn't very helpful. 这不是很有帮助。

I can think of various ways of representing such a combined error type that are more useful than Any (eg Validation[Error1 \\/ Error2, Result] to store either, Validation[String, Result] translating to an error message, etc) but they all have drawbacks. 我可以想到各种方法来表示比Any更有用的组合错误类型(例如, Validation[Error1 \\/ Error2, Result]来存储, Validation[String, Result]转换为错误消息等)但是它们都有缺点。

Is there an idiomatic way to do this? 这是否有惯用的方法?

Since nobody has had a better idea I'll leave my answer for future reference. 由于没有人有更好的想法,我会留下我的答案以供将来参考。

As said in the comment the best way is to create a error hierarchy: 如评论中所述,最好的方法是创建错误层次结构:

trait GenericError {  /* some commond fields */}
case class MyNumericError(/* fields */)

and then use leftMap on a validation to generate appropriate errors: 然后在验证时使用leftMap来生成适当的错误:

Validation.fromTryCatchNonFatal(...).leftMap(t => MyNumericError(...))

This approach has two advantages 这种方法有两个优点

  • First you will always have a Validation[GenericError, T] so not having different types on the left part of that validation 首先,您将始终具有Validation[GenericError, T]因此在验证的左侧部分没有不同的类型
  • The second is that this helps generate meaningful errors for both developers and service user, also note that generating an error where you have many context informations helps in this process. 第二,这有助于为开发人员和服务用户生成有意义的错误,同时请注意,在您有许多上下文信息的情况下生成错误有助于此过程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM