HiveBrain v1.2.0
Get Started
← Back to all entries
debugMinor

Exception handling for timing CouchBase fetch

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
handlingexceptionfetchtimingcouchbasefor

Problem

override def get(key: String): Option[Any]  = {
  val timer = couchbaseMetricsTimer.time()
  try { // Any way (is it more elegant?) to avoid the try/catch/finally?
    Option(couchBaseClient.get(key))
  } catch {
    case e: Exception => couchbaseFailureMetricCounter.inc(); throw e
  } finally {
    timer.stop()
  }
}


Note the clients of this code are expecting exceptions in case of failures.

Solution

You could use Try utility.

But the main concern is that it doesn't support finally statement out-of-the-box.

This can be achieved with some Try enhancement's value class (by Viktor Klang):

implicit class TryOps[T](val t: Try[T]) extends AnyVal {
  def eventually[Ignore](effect: => Ignore): Try[T] = {
    val ignoring = (_: Any) => { effect; t }
    t transform (ignoring, ignoring)
  }
}


Consider this code:

val timer = couchbaseMetricsTimer.time()
val tryClient =
  Try(couchBaseClient.get(key)) map { //convert success result
    Option(_)
  } recover { //process failure result
    case e: Exception => couchbaseFailureMetricCounter.inc(); throw e
  } eventually { //perform "finally" block
    timer.stop()
  }

//return actual result
tryClient.get


It's not less, by more idiomatic, so it's up to you which way to choose.

Here are more references to discover.

Note: you can put TryOps into package object of some of your root package f.e. com.mycompany, and then you can use it everywhere in your project.

Code Snippets

implicit class TryOps[T](val t: Try[T]) extends AnyVal {
  def eventually[Ignore](effect: => Ignore): Try[T] = {
    val ignoring = (_: Any) => { effect; t }
    t transform (ignoring, ignoring)
  }
}
val timer = couchbaseMetricsTimer.time()
val tryClient =
  Try(couchBaseClient.get(key)) map { //convert success result
    Option(_)
  } recover { //process failure result
    case e: Exception => couchbaseFailureMetricCounter.inc(); throw e
  } eventually { //perform "finally" block
    timer.stop()
  }

//return actual result
tryClient.get

Context

StackExchange Code Review Q#61057, answer score: 3

Revisions (0)

No revisions yet.