Lesson 2

Partial Function

Error Handling in Scala

Traditional error handling

import java.net.URL

def parseURL(url: String): URL = new URL(url)

//traditional try/catch
def parseURL(url: String): URL = 
try {
    new URL(url)
} catch {
  case e: MalformedURLException => println("Oh noes, pls try harder")  
}
  • Scala supports traditional Java style try/catch
  • Not as good when trying to compose multiple calls

Functional Error handling

scala.util.Try

One of more functional and composable ways to handle errors and failures

Try structure

sealed abstract class Try[T] {...}

final case class Success[T](value: T)
  extends Try[T] {...}

final case class Failure[T](exception: Throwable)
  extends Try[T] {...}

Implements higher-order methods

  • map

  • flatMap

  • filter (withFilter)

  • ... and others

(spot the similarity to Option)

mapping

parseURL("http://hotels.com").map(_.getProtocol)
// results in Success("http")
import java.io.InputStream

def inputStreamForURL(url: String): Try[InputStream] = parseURL(url).flatMap { url =>
  Try(url.openConnection()).flatMap(connection => Try(connection.getInputStream))
}

flatMapping

filtering

parseURL("http://hotels.com").filter(url => url.getProtocol == "ftp")
//results in Failure(java.util.NoSuchElementException)
import java.io.InputStream

def inputStreamForURL(url: String): Try[InputStream] = parseURL(url).flatMap { url =>
  Try(url.openConnection()).flatMap(connection => Try(connection.getInputStream))
}
import java.io.InputStream

def inputStreamForURL2(url: String): Try[InputStream] = {
  for {
    parsedUrl <- parseURL(url)
    connection <- Try(parsedUrl.openConnection())
    inputStr <- Try(connection.getInputStream)
  } yield inputStr
}

Translation into for-comprehensions

for-comprehension version 

flatMap version

def parseURL(url: String): Try[URL] = Try(new URL(url))

val result = parseURL("http://www.hotels.com")

result match {
  case Success(url) => println(url)
  case Failure(e) => println(s"An error occurred: ${ex.getMessage}")
}

Consuming Try 

parseURL("garbage") recover {
  case e: MalformedURLException => "Please make sure to enter a valid URL"
  case _ => "An unexpected error has occurred. We are so sorry!"
}
// returns Success(Please make sure to enter a valid URL)

Matching on a failure with recover

Pattern Matching

deck

By Povilas Lape

deck

  • 88