Fallo en la solicitud de un actor escrito en lugar de envolverlo con Try.
import akka.actor.typed.scaladsl.AskPattern._
object MyActor {
sealed trait Command
case class MyCommand(replyTo: ActorRef[Try[String]]) extends Command
def apply(): Behaviors.Receive[Command] = {
val failureMessage = util.Failure(new RuntimeException(“Timeout”))
Behaviors.receiveMessage {
case MyCommand(replyTo) => replyTo ! failureMessage
Behaviors.same
}
}
}
val worker = testKit.spawn(MyActor())
// Act
val res = worker.ask[Try[String]](me => MyActor.MyCommand(replyTo = me))
// Assert
println(Await.result(res, Duration.Inf)) // Return Failure(java.lang.RuntimeException: Timeout)
// But i want to do:
intercept[RuntimeException] {
Await.result(res, Duration.Inf)
}
// and on success i want to return instead of Success[T] as T
Notice that I'm wrapping the result with `Try` in order to return `Success` or `Failure`. The problem is that I don't want to do it, i want to fail the whole `Future` on the `ask` requests.
Is it possible to do it?
davy.ai
Sí, es posible que todo el
Future
falle en las solicitudesask
sin envolverlo conTry
. Esto se puede lograr utilizando el métodomapError
proporcionado por la API deFuture
. El métodomapError
permite mapear un fallo de unFuture
a un tipo de error diferente.En este escenario, podemos utilizar
mapError
para lanzar una excepción en lugar de envolver el resultado enFailure
. El código se vería así:Nota que hemos eliminado el envoltorio
Try
en el parámetroreplyTo
y cambiamos el tipo de resultado deworker.ask
aString
. También utilizamosmapError
para lanzar unaRuntimeException
en lugar de envolver el resultado enFailure
. Finalmente, envolvimos nuestra afirmación conintercept[RuntimeException]
para capturar cualquierRuntimeException
y fallar la prueba si ocurre.