2013-12-22 9 views
5

Wenn ein Scala-Future fehlschlägt und es keine Fortsetzung gibt, die diesen Fehler "beobachtet" (oder die einzigen Fortsetzungen map/flatMap verwenden und im Fehlerfall nicht ausgeführt werden), bleiben Fehler unentdeckt . Ich möchte, dass solche Fehler zumindest protokolliert werden, damit ich Fehler finden kann.Abfangen nicht behandelter Fehler in Scala-Futures

Ich verwende den Begriff "beobachteter Fehler", weil in .Net Tasks die Möglichkeit besteht, "unbeobachtete Taskausnahmen" zu erfassen, wenn das Task-Objekt vom GC erfasst wird. Ähnlich können bei synchronen Methoden nicht erfasste Ausnahmen, die den Thread beenden, protokolliert werden.

In Scala-Futures würde das "Beobachten" eines Fehlers bedeuten, dass eine Fortsetzungsfunktion oder ein anderer Code die Ausnahme liest, die im zukünftigen Wert gespeichert ist, bevor diese Zukunft entsorgt wird. Ich bin mir bewusst, dass die Finalisierung nicht deterministisch oder zuverlässig ist, und vermutlich wird sie deshalb auch nicht dazu verwendet, unbehandelte Fehler zu erfassen, obwohl .Net das gelingt.

Gibt es einen Weg, dies in Scala zu erreichen? Wenn nicht, wie sollte ich meinen Code organisieren, um unbehandelte Fehler zu vermeiden?

Heute habe ich andThen checkResult an verschiedene Futures angehängt. Aber es ist schwer zu wissen, wann und wann es nicht verwendet werden sollte: Wenn eine Bibliotheksmethode eine Zukunft zurückgibt, sollte sie Fehler nicht selbst prüfen und protokollieren, da der Bibliotheksbenutzer den Fehler verarbeiten kann, so dass die Verantwortung auf den Benutzer entfällt. Während ich Code bearbeite, muss ich manchmal Prüfungen hinzufügen und manchmal, um sie zu entfernen, und solche manuelle Verwaltung ist sicherlich falsch.

+0

mögliches Duplikat von [Wie bekomme ich Ausnahmen, die in einer Scala-Zukunft geworfen werden?] (Http://stackoverflow.com/questions/6229778/how-do-i-get-hold-of-exceptions-thrown- in-a-scala-future) –

+4

Es ist kein Duplikat. Ich weiß, wie man aus einer Zukunft eine Ausnahme macht. Was ich brauche, ist eine Möglichkeit, Bugs zu behandeln, bei denen der Programmierer * vergessen hat *, die Ausnahme von der Zukunft zu bekommen - entweder sie zu verhindern oder sie abzufangen, wenn sie auftreten. – danarmak

Antwort

3

Ich habe festgestellt, dass es keine Möglichkeit gibt, unbehandelte Fehler in Scala-Futures generisch zu bemerken.

5

Sie können einfach Future.recover in der Funktion verwenden, die die Zukunft zurückgibt.

So zum Beispiel könnten Sie einfach „log“ den Fehler und rethrow die ursprüngliche Ausnahme, im einfachsten Fall:

def libraryFunction(): Future[Int] = { 
    val f = ... 
    f.recover { 
     case NonFatal(t) => 
     println("Error : " + t) 
     throw t 
    } 
} 

Beachten Sie die Verwendung von NonFatal alle Ausnahmetypen entsprechen ist es sinnvoll, zu fangen .
Dieser Wiederherstellungsblock könnte ebenfalls ein alternatives Ergebnis zurückgeben, wenn Sie dies wünschen.

+0

Ich hoffte auf einen Weg, Fehler zu entdecken, selbst wenn der Programmierer vergessen hat, nach einem Fehlerzustand zu suchen. Sieht so aus, als gäbe es keine solche Option. – danarmak

+0

Nein. Jede "Behandlung" einer Ausnahme von future entspricht im Allgemeinen dem Hinzufügen eines onComplete-Handlers. Daher werden Ergebnisse oder Ausnahmen nicht so getrennt, dass Sie erkennen können, ob eine Ausnahmebehandlung angehängt ist. –