I am using some client library and had some code that ignored a specific exception using scala.util.control.Exception.ignoring:
ignoring(classOf[ReallyNotThatExceptionalException]) {
  stuff()
}
Now that library changed to wrap all exceptionn in another exception class, which forced me to change my code to this:
try { stuff() }
catch {
  case e:WrapperException if e.getCause != null && e.getCause.isInstanceOf[ReallyNotThatExceptionalException] => { }
}
So what I'm looking for a more readable way to express "catch exceptions that are caused by".
0__'s answer is good, but it would be better if you were not forced to write a specific object (CausedByFoo) for each potential exception.
As it happens, there is not much to change to end up with a generic CausedBy helper object:
class Foo(message: String) extends Exception(message)
class Bar(cause: Throwable) extends Exception(cause)
object CausedBy {
  def unapply(e: Throwable): Option[Throwable] = Option(e.getCause)
}
def test(block: => Unit): String = 
  try {
    block
    "ok"
  } catch {
    case CausedBy(ex: Foo) => "not ok: " + ex.getMessage
  }
test(println("hello"))
test(println("hello".toInt)) // uncaught exception
test(throw new Bar(new Foo("Ooops, foo error!"))) // caught
As should be obvious, you can use CausedBy with any exception (by example by doing case CausedBy(ex: Baz).
You can even nest it to handle an exception caused by an exception caused by an exception (by doing something like case CausedBy(CausedBy(ex: Foo))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With