Part2: Scala – Error handling

Error Handling

When we start a new language, error handling is an important function that developers need to know it. How well scala supports you doing so. In this article, I will talk about Try type, how to use it?

Throwable and Exception 

When we write a function to access a database, what do you need to do in this function?. We suppose that it gets account list, but what happens if our database lost a connection or input data incorrect ?. We need to control all case for our program does not stop running smoothly

In other languages as C#, PHP…, we can use Try  to help us control exception of a program. Scala can do like that too. It can catch all exceptions from programs, recognize a type of error and throwable a new definition of exception

try{

  // ... 

} catch {

  case ioe: IOException =>... // more specific cases first ! 

  case e: Exception => ...

}

Using Try[T] to compose on exceptions 

One of the most important characteristics of the Try type is that, like Option. This allows you to chain operations on Try values and catch any exceptions that might occurs

Let’s look at:

def functionName(): Try[T] = Try {

  // Return a Success value

  // Return a Failure value

}

Function above will return a Try value. If it run correct, it will be return a results in Success(T). It errors occurs, it will be return Failure(exception information). Let’s look at example:

import scala.util.Try

def stringToInt(str: String): Try[Int] = Try(str.toInt)

// Return Success

println(stringToInt("120"))

// Return Failure

println(stringToInt("12a"))

I will build a function stringToInt to convert a string to Int. You can see that input data is a string, an output is a Try[Int].

If input data is string number, function str.toInt will run correctly, it returns a Success(120) value. The same Option Type you can use  stringToInt(“120”).get to get real data. It will be 120

If input data isn’t string number, it will return a Failure(java.lang.NumberFormatException: For input string: “12a”).

we can understand a Try Type, but how is it running? how to handling it? I will show you some way to handling Try value

Pattern Matching 

It’s a simple way of handling a Try type, we can use Pattern Matching

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

// use Match

stringToInt("10") match {

  case Success(number) => println(number)

  case Failure(e) => println(e.getMessage)

}

We can use Success(number) to get a return value. Our example, it returns a Try[Int], so Pattern Matching will return a Success[Int]. It’s number that we expected.

If our function returns a Try[T], Pattern matching will match a Success[T]

It errors occurs, Pattern matching will return a Failure(e: Exception). We can know the type of error and message of the system  

Mapping, Flat mapping, For 

You can use Mapping or Flat mapping to handling a Try value.

Mapping example: 

// Use map 

stringToInt("100").map(number => println(number))

Function return a Try[Int], so we can use map to get a return value. In above example, it will assign into number variable. If function return multi Try like Try(Try(Int)), we can use one more map inside to get Int value

Try(stringToInt("100")).map { 
  number => number.map(println(_)) 
}

Flat mapping example: 

// Use flat map 
val number = Try(stringToInt("5")).flatMap(Try(_)) 
println(number)

As you know, When we have a return value with multi Option(Option(Int)), then Flatmap is useful to get Int value. Try the same like that. When function returns a multi Try(Try(Int)), we can get a number without Map inside like above example. Please remember that FlatMap will return a function inside

For example: 

//use for 
val numFor = for { 
  num <- stringToInt("13") 
} yield num 
println(numFor)

You can use For to get a value of Try type. For will use “<-” to extract the number of Try value. If function returns a normal number without Try value, we need to use “=” instead of “<-“

Recover 

If you want to get Failure from a function, we can use Recover to check it

Example:

// Recover to check exception 
stringToInt("12a").recover { 
  case e: NumberFormatException => println(e.getMessage) 
}.map(println(_)).getOrElse(println("unknow error"))

In the example above, I will catch an exception: NumberFormatException and show an error message. Other error it will be skipped. It runs correct, we will display number. It is good for us to check these immortal errors that we need to save and fix it

You May Also Like

About the Author: Nguyen Dinh Thuc

Leave a Reply

Your email address will not be published.