How to refactor a function that throws exceptions?

主宰稳场 提交于 2020-01-04 06:08:36

问题


Suppose I am refactoring a function like this:

def check(ox: Option[Int]): Unit = ox match {
  case None => throw new Exception("X is missing")
  case Some(x) if x < 0 => throw new Exception("X is negative")
  case _ => ()
}

I'd like to get rid of the exceptions but I need to keep the check signature and behavior as is, so I'm factoring out a pure implementation -- doCheck:

import scala.util.{Try, Success, Failure}

def doCheck(ox: Option[Int]): Try[Unit] = ???

def check(ox: Option[Int]): Unit = doCheck(ox).get

Now I am implementing doCheck as follows:

def doCheck(ox: Option[Int]): Try[Unit] = for {
  x <- ox toTry MissingX()
  _ <- (x > 0) toTry NegativeX(x)
} yield ()

Using the following implicits:

implicit class OptionTry[T](o: Option[T]) { 
  def toTry(e: Exception): Try[T] = o match {
    case Some(t) => Success(t)
    case None    => Failure(e)
  }
}

implicit class BoolTry(bool: Boolean) { 
  def toTry(e: Exception): Try[Unit] = if (bool) Success(Unit) else Failure(e) 
}

Does it make sense ?

P.S. The implicits certainly add more code. I hope to replace OptionTry with an implicit from scalaz/cats someday and maybe find an analog for BoolTry.


回答1:


You could refactor with a loan pattern and Try.

def withChecked[T](i: Option[Int])(f: Int => T): Try[T] = i match {
  case None => Failure(new java.util.NoSuchElementException())
  case Some(p) if p >= 0 => Success(p).map(f)
  case _ => Failure(
    new IllegalArgumentException(s"negative integer: $i"))
}

Then it can be used as following.

val res1: Try[String] = withChecked(None)(_.toString)
// res1 == Failure(NoSuchElement)

val res2: Try[Int] = withChecked(Some(-1))(identity)
// res2 == Failure(IllegalArgumentException)

def foo(id: Int): MyType = ???
val res3: Try[MyType] = withChecked(Some(2)) { id => foo(id) }
// res3 == Success(MyType)


来源:https://stackoverflow.com/questions/37906243/how-to-refactor-a-function-that-throws-exceptions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!