Try with exception logging

Define the following helper:

import scala.util.{Try, Failure}

def LogTry[A](computation: => A): Try[A] = {
  Try(computation) recoverWith {
    case e: Throwable =>
      log(e)
      Failure(e)
  }
}

Then you can use it as you would use Try, but any exception will be logged through log(e).


Starting Scala 2.13, the chaining operation tap can be used to apply a side effect (in this case some logging) on any value while returning the original value:

import util.chaining._

val x = Try("aa".toInt).tap(_.failed.foreach(println))
// java.lang.NumberFormatException: For input string: "aa"
// x: Try[Int] = Failure(java.lang.NumberFormatException: For input string: "aa")

Or an equivalent pattern matching version:

val x = Try("aa".toInt).tap { case Failure(e) => println(e) case _ => }
// java.lang.NumberFormatException: For input string: "aa"
// x: Try[Int] = Failure(java.lang.NumberFormatException: For input string: "aa")

The tap chaining operation applies a side effect (in this case println or some logging) on a value (in this case a Try) while returning the original unmodified value on which tap is applied (the Try):

def tap[U](f: (A) => U): A