Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scala.util.Failure.recoverWith broken in Scala 2.13.0-M5 #11242

Closed
sjrd opened this issue Nov 4, 2018 · 1 comment
Closed

scala.util.Failure.recoverWith broken in Scala 2.13.0-M5 #11242

sjrd opened this issue Nov 4, 2018 · 1 comment

Comments

@sjrd
Copy link
Member

sjrd commented Nov 4, 2018

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) }
  }
@viktorklang
Copy link

See #7390

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants