Closed
Description
See scala-js/scala-js#3480 (comment)
On 2.13.0-M5:
C:\Users\Sepi>scala
Welcome to Scala 2.13.0-M5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_60).
Type in expressions for evaluation. Or try :help.
scala> import scala.util._
import scala.util._
scala> :paste
// Entering paste mode (ctrl-D to finish)
val e: Try[Int] = Failure(new Exception("dfd"))
val pf: PartialFunction[Throwable, Int] = {
case _: RuntimeException => 1
}
val e2 = e.recoverWith(pf.andThen(Try(_)))
println(e2)
// Exiting paste mode, now interpreting.
Failure(java.lang.ClassCastException: java.lang.Object cannot be cast to scala.util.Try)
e: scala.util.Try[Int] = Failure(java.lang.Exception: dfd)
pf: PartialFunction[Throwable,Int] = <function1>
e2: scala.util.Try[Int] = Failure(java.lang.ClassCastException: java.lang.Object cannot be cast to scala.util.Try)
On 2.12.6:
C:\Users\Sepi>scala
Welcome to Scala 2.12.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_60).
Type in expressions for evaluation. Or try :help.
scala> import scala.util._
import scala.util._
scala> :paste
// Entering paste mode (ctrl-D to finish)
val e: Try[Int] = Failure(new Exception("dfd"))
val pf: PartialFunction[Throwable, Int] = {
case _: RuntimeException => 1
}
val e2 = e.recoverWith(pf.andThen(Try(_)))
println(e2)
// Exiting paste mode, now interpreting.
Failure(java.lang.Exception: dfd)
e: scala.util.Try[Int] = Failure(java.lang.Exception: dfd)
pf: PartialFunction[Throwable,Int] = <function1>
e2: scala.util.Try[Int] = Failure(java.lang.Exception: dfd)
Note that 2.13.0-M5 has thrown a ClassCastException
, and it has been swallowed by the Try
as Failure(ClassCastException)
. 2.12.6 correctly reports a Failure(Exception)
.
That's because Failure.recoverWith
is broken. It should be something like:
override def recoverWith[U >: T](pf: PartialFunction[Throwable, Try[U]]): Try[U] = {
val marker = Statics.pfMarker
try {
val v: Any = pf.applyOrElse(exception, ((x: Throwable) => marker))
if (marker ne v.asInstanceOf[AnyRef]) v.asInstanceOf[Try[U]] else this
} catch { case NonFatal(e) => Failure(e) }
}