Match nested exceptions in Scala

(, en)

Option 1

// src/main/scala/NestedExceptionMatch.scala
object CausedBy {
  def unapply(e: Throwable): Option[Throwable] = Option(e.getCause)
}

object ClientNestedException1 {
  def shouldRetryRequest(ex: Throwable): Boolean = {
    ex match {
      case HttpError(_, statusCode) if statusCode == StatusCode.BadGateway => true
      case ex @ CausedBy(nex: SSLHandshakeException)                       => true
      case _                                                               => false
    }
  }
}

Option 2

(I prefer this option, less fuzz and less nesting)

// src/main/scala/NestedExceptionMatch.scala
object ClientNestedException2 {
  def shouldRetryRequest(ex: Throwable): Boolean = {
    (ex, Option(ex.getCause)) match {
      case (HttpError(_, statusCode), _) if statusCode == StatusCode.BadGateway => true
      case (_: SttpClientException, Some(_: SSLHandshakeException))             => true
      case _                                                                    => false
    }
  }
}