23. Try { } - RobertMakyla/scalaWiki GitHub Wiki
try{} catch{}
try {
// sth risky
} catch {
case e:Throwable => log.error(e.getMessage)
}
It's like in JAVA - It's not a functional way !!!
Try
Either[A] - might be Left[A] or Right[A]
Option[A] - might be Some[A] or None
Try[A] - might be Success[A] or Failure[A]
Success[A] - contains A : Success(A)
Failure[A] - contains Throwable: Failure(Throwable)
We should enclose a risky code in Try() and this returns Try[A]
import scala.util.Try
import java.net.URL
def parseURL(url: String): Try[URL] = Try( new URL(url) )
parseURL("blee") match {
case Success(goodUrl) => println(s"url is ok : $goodUrl")
case Failure(me: MalformedURLException) => println(s"malformed : ${me.getMessage}")
case Failure(t) => println(s"throwable : ${t.getMessage}")
}
parseURL("blee").isSuccess // --> false
parseURL("blee").toOption // --> Option[URL]
parseURL("blee").map( url => url.getHost) // --> Failure(MalformedURLException)
Try.map
I can chain many map() which returns Try[Try[Try[A]]] :
def inputStreamForURL(url: String): Try[Try[Try[InputStream]]] = parseURL(url).map { u =>
Try(u.openConnection()).map(conn => Try(conn.getInputStream))
}
Try.flatmap
I can chain many flatmap() which returns Try[A] :
def inputStreamForURL(url: String): Try[InputStream] = parseURL(url).flatMap { u =>
Try(u.openConnection()).flatMap(conn => Try(conn.getInputStream))
}
###Recover
This is alternative to getOrElse() to establish returning value in case of failure
val content = parseURL("blee") recover {
case e: MalformedURLException => URL("http://default.host.1")
case _ => URL("http://default.host.0")
}
Now, with recover, this will always return Success because in recover{} we show which success to return in case of failure. So we can safely call .get()
KATA flatmap/for-comprehension on Try - if each operation is throwable
import scala.util.Try
import java.net.URL
Try(new URL("http://www.google.com")).flatMap { url =>
Try(url.openConnection()).flatMap{ conn =>
Try(conn.getInputStream)
}
}
or
import scala.util.Try
import java.net.URL
for{
url <- Try(new URL("http://www.google.com"))
conn <- Try(url.openConnection())
in <- Try(conn.getInputStream )
} yield in
możnaby zrobić tak pisanie do pliku:
import java.io.FileWriter
Try(new FileWriter("C:\\Temp\\file.txt")).flatMap { fw =>
Try{fw.write("content");fw.close()}
}
tylko tu jest problem że jak sie wywali na fw.write() to nie zamknie fw.close(), nawet jak zrobimy na tym ostatnim Try.recover to też nie zamknie bo nie ma uchwytu na fw, więc try{}finally{} jest tu niezbędne:
KATA Try and Writing to file:
def aroundWriter(fw: FileWriter)(f: FileWriter => Unit) = try f(fw) finally fw.close()
Try(
aroundWriter(new FileWriter(file, false)) {
fw => fw.write("some content")
}
) match {
case Success(_) => \/-(())
case Failure(e) => -\/(e.getMessage)
}