Error handling – functional ways

Handling error là việc cực kì quan trọng dù bạn có sử dụng bất kì ngôn ngữ nào, có rất nhiều cách để handle error, một trong những cách đơn giản nhất:

def divide(a: Int, b: Int): Float = {
 try{
    a/b
 } catch {
    case e: IllegalArgumentException => throw new IllegalArgumentException
    case _: IOException => throw new IOException()
 }
}

Khi gọi hàm divide(1,0) sẽ trả ra một exception. Nhìn thì đúng, tuy nhiên có vẻ không giống như là một functional way lắm, và trông bình thường quá. Có một vài cách tốt hơn để handle exception theo kiểu functional như sau:
1. Option

def divide(a: Int, b: Int): Option[Float] = {
  try{
    Some(a/b)
  } catch {
    case e: IllegalArgumentException => None
  }
}

Some và None rõ ràng sẽ giúp chúng ta tránh việc phải throw ra exception
2. Either
một cách phổ biến hơn để handle error là dùng Either , nó trả về một kiểu là nếu không phải là Trái (Left) thì sẽ là Phải (Right). Thông thường người ra dùng Right để đại diện cho success và Left để đại diện cho Failure.

def divide(a: Int, b: Int): Either[Exception, Float] = {
  if (b == 0) Right(a/b)
  else Left(Exception)
}

Kiểu này cũng rất tốt 😀
3. Try
Đây là kiểu mình thích sử dụng nhất

def divide(a: Int, b: Int): Try[Float] = {
  Try{
     if (b == 0) throw new Exception
     else a/b
  }
}

khi gọi hàm divide(1,0), chúng ta có thể handle exception:

val a = divide(1,0) match {
  case Success(result) => result
  case Failure(result) => {
    println(result)
    "pls try another denominator"
  }
}

Sử dụng Try[] rất hiệu quả, đặc biệt trong việc phát triển các project phức tạp, khi mà các bạn muốn bảo vệ hệ thống khỏi một đống các exception hoặc handle những custom exception một cách dễ dàng hơn

Tham khảo: https://tersesystems.com/2012/12/27/error-handling-in-scala/

Add a Comment

Scroll Up