Ich möchte den folgenden Code eine benutzerdefinierte Nachricht zurückgeben, wenn eine der Methoden callfuture1()
oder callfuture2()
eine Ausnahme auslöst. Mein Verständnis war, wenn einer der Zukunft fehlschlägt, f
wäre eine gescheiterte Zukunft.nicht handhabbare Ausnahme von zukünftigem Fehler
Wenn jedoch callfuture1
eine Ausnahme auslöst. f.onFailure
wird nicht ausgeführt. Stattdessen sehe ich, dass der Aufruf-Stack an der Codezeile in callFuture1()
angehalten wurde, wo Ausnahme aufgetreten ist und ein interner Standardfehler zurückgegeben wird. Warum passiert das?
val f = for {
x <- callfuture1()
y <- callfuture2()
} yield y
f.onFailure {
//send an internalserver error with some custom message
}
f.map {
//send data back
}
==== ==== Update
i aus den Antworten zu sehen, dass potenzielles Problem ist, dass Ausnahme außerhalb der Zukunft geworfen wird und damit nicht mein Code Zukunft das nicht gelang fangen . Also habe ich den Code so geändert, dass Ausnahme nur innerhalb der Zukunft auftritt. Ich kann das Verhalten, das ich sehe, immer noch nicht erklären. (Ich frage mich, ob es etwas mit Play-Rahmen zu tun.)
def controllerfunction(id: String) = Action.async{
val f = for{
x <- callfuture1(id)
y <- callfuture2(x)
} yield y
y.onFailure{case t =>
println("This gets printed");
Ok("shit happened, but i am still ok")}
y.map{resp:String => Ok(resp)}
}
def callfuture1(id: String):Future[Obj1] = {
for {
val1 <- callfuture1.1(id)
val2 <- callfuture1.2(val1)
} yield val2
}
def callfuture1.2:Future[Obj3] = Future{
thrown new Exception("TEST ME");
}
def callfuture 1.1:Future[Obj4] = {...}
def callfuture2: Future[String] = {....}
Erwartung. Verfahren callfuture1.2 löst eine Ausnahme in der Zukunft, so meine Erwartung onFailure ausgeführt werden soll, (die ausgefuehrt wird,) und die Antwort zurück sollte „Scheiße passiert ist, aber ich bin immer noch in Ordnung“
Aktualität Das Play-Framework gibt InternalServerError zurück und ich sehe den Fehler-Stack auf meiner Konsole. Ich sehe, dass der Printlin ("Dies wird gedruckt") ausgeführt wird.
Kann nicht verstehen, was passiert. Irgendwelche Einsichten?
==== Update 2 =====
prüfte ich, dass das Problem nur, wenn innerhalb Steuerung des Spiels Rahmen genannt geschieht (i unter Verwendung von 2,5 bin spielen). Als eigenständiges Scala-Programm funktioniert alles wie erwartet. Ich glaube, dass die Behandlung von Spielfehlern die nicht verarbeitete Ausnahme abfängt und die Stapelverfolgung druckt. Ich denke, das sollte nur in der Entwicklungsumgebung passieren.
Versuchen Sie 'val f1 = callfuture1(); val f2 = Anrufzukunft2; f = für {x <- f1; y <- f2} Ausbeute y '. Der Unterschied besteht darin, dass Futures in Ihrem Fall nacheinander ausgeführt werden (y wartet auf den Abschluss von callfuture1). – chuwy
Was meinen Sie mit "stack stopped"? Was ist "interner Standardfehler"? Woher weißt du, dass onFailure nicht ausgeführt wird? Was ist der eigentliche Fehler? – Dima
Auch. Beachten Sie, dass OnFailure nur für Nebenwirkungen verwendet werden kann. Es kann die in der "Zukunft" enthaltene Ausnahme nicht ändern. Wenn Sie mit der Ausnahme fiedeln möchten, müssen Sie 'transform' oder' recover' verwenden. – Dima