例子
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
}
請注意,Try為了回傳Successor ,我將結果包裝為Failure。問題是,我并不想這樣做,我想失敗,整個Future的ask請求。
有可能做到嗎?
uj5u.com熱心網友回復:
對于回應將是成功回應還是失敗回應的詢問,在 Akka Typed 中,這最好通過使用askWithStatus和調整協議來實作StatusReply:
import akka.pattern.StatusReply
object MyActor {
sealed trait Command
case class MyCommand(replyTo: ActorRef[StatusReply[String]]) extends Command
// can also wrap a Throwable, but it's generally advised to wrap a string
val failure = StatusReply.Error("Timeout")
def apply(): Behavior[Command] =
Behaviors.receiveMessage {
case MyCommand(replyTo) =>
replyTo ! failure
Behaviors.same
}
}
然后,執行提問:
val res: Future[String] = worker.askWithStatus[String](MyActor.MyCommand(_))
res 將要:
- 完成與
string當演員被要求與回答StatusReply.Success(string) - 失敗了
StatusReply.ErrorMessage(errorString),如果演員被要求與回答StatusReply.Error(errorString) - 失敗的
x,如果演員被要求與回答StatusReply.Error(x: Throwable) ask如果在收到回應之前達到超時,通常會出現例外失敗
至于為什么建議包裝 String 錯誤訊息,這是因為通常情況下,請求演員做某事的代碼不應該對演員的內部結構了解足夠多的例外訊息之外的任何部分和(也許)例外的型別是有意義的。如果您不愿意向 Web 或 API 使用者公開該詳細資訊(例如堆疊跟蹤),則您可能不應該在詢問回應中公開它。如果您在餐廳點菜,而廚房的廚師將平底鍋和您的食物放在地板上,您是否需要服務員(您的 API 到廚房)回來告訴您“廚師將您的食物掉在地板上? ” 或者服務員或經理過來說“對不起,您的訂單會延遲,在這里”就足夠了
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/393588.html
下一篇:AkkaHttp路由測驗與formFields導致UnsupportedRequestContentTypeRejection
