scalagenericsfunctional-programmingtype-erasurescala-template

Scala: abstract type pattern A is unchecked since it is eliminated by erasure


I am writing the function that can catch exceptions of the certain type only.

def myFunc[A <: Exception]() {
    try {
        println("Hello world") // or something else
    } catch {
        case a: A => // warning: abstract type pattern A is unchecked since it is eliminated by erasure
    }
}

What is the corrent way to bypass jvm type erasure in such case?


Solution

  • You could use ClassTag like in this answer.

    But I'd prefer this approach:

    def myFunc(recover: PartialFunction[Throwable, Unit]): Unit = {
      try {
        println("Hello world") // or something else
      } catch {
        recover
      }
    }
    

    Usage:

    myFunc{ case _: MyException => }
    

    Using ClassTag:

    import scala.reflect.{ClassTag, classTag}
    
    def myFunc[A <: Exception: ClassTag](): Unit = {
      try {
        println("Hello world") // or something else
      } catch {
        case a if classTag[A].runtimeClass.isInstance(a) =>
      }
    }
    

    Note also that in general you should use Try with recover method: Try will catch only NonFatal exceptions.

    def myFunc(recover: PartialFunction[Throwable, Unit]) = {
      Try {
        println("Hello world") // or something else
      } recover {
        recover
      }.get // you could drop .get here to return `Try[Unit]`
    }