Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Try with exception logging

Scala's Try is very useful.

I'd like to use that pattern, but log all exceptions.

How can I do this?

like image 605
SRobertJames Avatar asked Jun 24 '14 19:06

SRobertJames


People also ask

What is exception logging?

The exception log is a rolling collection of 4 files; when a file is full, data is added to the next file. When the last file has been filled, data starts to be added to the first file, overwriting the previous data there. This cycle of writing continues, ensuring that the newest data is retained.

How do you log Try except in Python?

If you want to log a formatted exception at a log level other than error you must use exc_info=True. @ChrisJohnson - you could simply use logging. exception() in your example...

Should you log before throwing exception?

Don't Log and Throw No matter which approach you take when handling exceptions, log the exception at the same time you handle the exception. If you log the exception and then throw it, there's a chance that the exception will be logged again further up the call stack, resulting in two log events for the same error.


2 Answers

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).

like image 189
sjrd Avatar answered Oct 03 '22 22:10

sjrd


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

like image 30
Xavier Guihot Avatar answered Oct 03 '22 22:10

Xavier Guihot