Skip to content

Instantly share code, notes, and snippets.

@SystemFw
Last active July 13, 2017 13:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SystemFw/06d558791b35c807b55153e7b0343f36 to your computer and use it in GitHub Desktop.
Save SystemFw/06d558791b35c807b55153e7b0343f36 to your computer and use it in GitHub Desktop.
Logging failures on Task
import scalaz.{-\/, \/-}
import scalaz.concurrent.Task
import scalaz.syntax.monad._
/*
* Easily adaptable to Monix, cats, fs2, cats-effect and so on
*/
object Logger {
sealed trait Level
object Level {
case object Error extends Level
case object Info extends Level
case object Warn extends Level
case object Debug extends Level
}
implicit class LogFailures[A](t: Task[A]) {
/**
* If the input task is a failure, it logs the resulting error
* and rethrows it within another failed task.
*
* If the input task is a success, does nothing.
*
* @param reporter A partial function that can return a different
* error and level for each error. If an error is
* not handled by `reporter`, its message (as
* given by `Throwable.getMessage`) is logged, at
* Debug Level
*
* @return A `Task[A]` that logs exceptions. Note that
* `logFailures`, as evident from its type, doesn't
* change the status of the task: a successful task
* remains successful, and a failed task remains failed.
*/
def logFailures(
reporter: PartialFunction[Throwable, (Level, String)]): Task[A] = {
def logMsgFor(e: Throwable): Task[Unit] =
reporter.lift(e) map {
case (level, msg) => log(msg, level)
} getOrElse {
log(e.getMessage, Level.Debug)
}
t.attempt flatMap {
case -\/(e) => logMsgFor(e) >> Task.fail(e)
case \/-(a) => Task.now(a)
}
}
}
private def log(msg: String, level: Level): Task[Unit] = Task.delay {
level match {
case Level.Error => logger.error(msg)
case Level.Info => logger.info(msg)
case Level.Warn => logger.warn(msg)
case Level.Debug => logger.debug(msg)
}
}
private val logger = journal.Logger[this.type]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment