scala에서 Exception처리에 대한 다양한 내용을 살펴본다.




1. try-catch 

자바와 비슷하게 처리한다.


object Main extends App {
def throwException: Unit = {
try {
println("A".toLong)
} catch {
case ex: Exception => println(ex)
} finally {
println("finally")
}
}
throwException
}


결과는 다음과 같다.


java.lang.NumberFormatException: For input string: "A"

finally




2. scala.util.Try-match



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

object Main extends App {
def throwException: Any = {
Try {
println("A".toLong)
} match {
case Success(result) => result
case Failure(exception) => exception
}
}
println(throwException)
}

결과는 다음과 같다.


java.lang.NumberFormatException: For input string: "A"



다른 예제


val loginUser =
Try(requestHeader.headers("loginUser")) match {
case Success(user) => user
case _ => ""
}




3. scala.util.Either 


Either는 Exception과 결과 값을 한번에 받을 수 있는 타입이다. 


def throwException: Either[Long, Throwable] = {
try {
Left("A".toLong)
} catch {
case ex: Exception => Right(ex)
} finally {
println("finally")
}
}
println(throwException)
println(throwException.merge)


결과는 다음과 같다.


finally

Right(java.lang.NumberFormatException: For input string: "A")

finally

java.lang.NumberFormatException: For input string: "A"



merge메소드는 예외와 리턴값 사이의 값을 하나로 병합한다. 





4. Exception.allCatch


1,2,3에 연관되어 Exception.allCatch라는 것이 있다. 이를 이용하면 try/catch를 한 줄에 사용할 수도 있다.

import scala.util.control.Exception._
println(allCatch.opt("A".toLong))
println(allCatch.toTry("A".toLong))
println(allCatch.either("A".toLong))

결과는 다음과 같다.


None

Failure(java.lang.NumberFormatException: For input string: "A")

Left(java.lang.NumberFormatException: For input string: "A")




5. scalaz의 disjunction

Either보다 더 좋은 형태의 예외 처리를 할 수 있다. 

scala 고수 개발자들이 scalaz의 disjunction을 추천한다고 하니 알아두면 좋을 것 같다.


\/를 사용하면서 해괴하지만, 간단해서 쓴다는...



val m = scalaz.\/.right[Throwable, Int](5).map(_ * 2)
println(m)
println(m.merge)

val n = scalaz.\/.left[Throwable, String](new Exception("1")).map(_.toLong)
println(n)
println(n.merge)

val ez : String \/ String = "a".right
println(ez)
println(ez.merge)


결과는 다음과 같다. Either와 비슷하게 쓰인다. 훨씬 either보다는 편하게 쓸 수 있다. 


\/-(10)

10


-\/(java.lang.Exception: 1)

java.lang.Exception: 1


\/-(a)

a



자세한 내용은 scalaz 7.2(https://github.com/scalaz/scalaz/tree/series/7.2.x)를 참고한다.



5. Validation


scalaz의 Validation도 사용할 수 있다. 


import scalaz._

def positive(i: Int): Validation[Exception, Int] = {
if (i > 0) Success(i) // <1>
else Failure(new NumberFormatException("should number > 0"))
}
println(positive(1))
println(positive(-1))


Posted by '김용환'
,