Ich möchte Fehlerbehandlung in meinem Spiel scala Web-Anwendung zu tun.Fehlerbehandlung Scala: Zukunft für Verständnis
Meine Anwendung spricht mit der Datenbank, um einige Zeilen zu holen, es folgt folgender Ablauf.
- erster Aufruf db einige Daten
- , um die Daten in ersten Anruf zu holen andere Daten von holen db
- eine Antwort bilden die empfangenen Daten von den letzten zwei db Anrufen verwenden.
Unten ist mein Pseudocode.
def getResponse(name: String)
(implicit ctxt: ExecutionContext): Future[Response] = {
for {
future1 <- callFuture1(name)
future2 <- callFuture2(future1.data)
future3 <- callFuture3(future1.data, future2.data)
} yield future3
}
Jede Methode im obigen Verständnis gibt eine Zukunft zurück, die Signatur dieser Methoden ist wie folgt.
private def callFuture1(name: String)
(implicit ctxt: ExecutionContext): Future[SomeType1] {...}
private def callFuture2(keywords: List[String])
(implicit ctxt: ExecutionContext): Future[SomeType2] {...}
private def callFuture3(data: List[SomeType3], counts: List[Int])
(implicit ctxt: ExecutionContext): Future[Response] {...}
Wie soll ich tun, Fehler/Fehlerbehandlung, in der folgenden Situation
- Wenn callFuture1 nicht Daten aus der Datenbank zu holen. Ich möchte eine entsprechende Fehlerantwort mit Fehlermeldung zurückgeben. Seit callFuture2 wird nur nach callFuture1 ausgeführt. Ich möchte callFuture2 nicht ausführen, wenn callFuture1 fehlgeschlagen ist/Fehler und Fehlermeldung sofort zurückgegeben werden soll. (Das Gleiche gilt für callFuture2 und callFuture3)
--edit--
Ich versuche, eine entsprechende Fehlerreaktion von getResponse() -Methode zurück, wenn entweder der callFuture ausfällt und nicht auf nachfolgende gehen FutureCalls.
Ich habe versucht, die folgenden, basierend auf Peter Neyens Antwort, aber gab mir einen Laufzeitfehler ..
def getResponse(name: String)
(implicit ctxt: ExecutionContext): Future[Response] = {
for {
future1 <- callFuture1(name) recoverWith {
case e:Exception => return Future{Response(Nil,Nil,e.getMessage)}
}
future2 <- callFuture2(future1.data)
future3 <- callFuture3(future1.data, future2.data)
} yield future3
}
Laufzeitfehler i
ERROR] [08/31/2015 02:09:45.011] [play-akka.actor.default-dispatcher-3] [ActorSystem(play)] Uncaught error from thread [play-akka.actor.default-dispatcher-3] (scala.runtime.NonLocalReturnControl)
[error] a.a.ActorSystemImpl - Uncaught error from thread [play-akka.actor.default-dispatcher-3]
scala.runtime.NonLocalReturnControl: null
Danke für diese Antwort. Es war hilfreich. Ich bin mir immer noch nicht sicher, ob das mein Problem löst. 1) Unter Verwendung des Ansatzes 1 (ohne implizite Klasse zu verwenden), wenn ich mit Future.failed (new Exception()) recovere, wird eine Ausnahme ausgelöst und meine Ausführung wird nicht fortgesetzt. Ich versuche, eine angemessene ResponseMessage zurückzugeben, wenn einer der zukünftigen Anruf fehlschlägt, ohne zu nachfolgenden zukünftigen calls (ich werde die Frage aktualisieren, um es klarer zu machen) – konquestor
Future.fail (neue Ausnahme (...)) verursacht die Ausführung zu werfen eine Ausnahme. Stattdessen möchte ich eine entsprechende Fehlermeldung zurückgeben, wenn etwas fehlschlägt/Fehler in futurecall. – konquestor
Versuchen Sie etwas wie das letzte Codebeispiel in meiner Antwort. –