Recursive Exceptions

A couple of weeks ago a former coworker send me this piece of code I had writtten:

@tailrec
private def getRootCause(throwable: Throwable): Throwable = {
  Option(throwable.getCause) match {
    case None => throwable
    case Some(cause) => getRootCause(throwable)
  }
}

D’oh! A nice endless loop. It caused quite nice spikes in garbage collection metrics and peak response times, and it took them a few days to find the root cause.

Ironically I had explicitly added @tailrec to make this piece of code behave nicely. If I had omitted it, StackOverflowExceptions would have triggered alerts almost immediately after deployment.

I am sorry.