Mehrere Fänge in der Versprechungskette behandeln
Ich bin noch Recht neu verspricht und bin mit bluebird zurzeit habe ich jedoch ein Szenario, wo ich nicht ganz sicher bin, wie Sie am besten damit umgehen.
Also ich habe z.B. ein Versprechen Kette innerhalb einer express app zum Beispiel so:
repository.Query(getAccountByIdQuery)
.catch(function(error){
res.status(404).send({ error: "No account found with this Id" });
})
.then(convertDocumentToModel)
.then(verifyOldPassword)
.catch(function(error) {
res.status(406).send({ OldPassword: error });
})
.then(changePassword)
.then(function(){
res.status(200).send();
})
.catch(function(error){
console.log(error);
res.status(500).send({ error: "Unable to change password" });
});
Also das Verhalten ich bin nach ist:
- Geht um Konto-Id
- Wenn es eine Ablehnung an diesem Punkt, Bombe und einen Fehler zurückgeben,
- Wenn es keine Fehler konvertieren Sie das Dokument wieder ein Modell
- Überprüfen Sie das Kennwort mit der Datenbank-Dokument
- Wenn die Passwörter nicht passen dann Bombe aus und geben Sie einen anderen Fehler
- Wenn kein Fehler Auftritt, gibt die Kennwörter ändern
- Dann wieder Erfolg
- Wenn alles andere schief gegangen ist, kehren 500
Also momentan fängt nicht scheinen zu stoppen die Verkettung, und das macht Sinn, also Frage ich mich, ob es eine Möglichkeit gibt mir irgendwie Kraft, die Ketten zu stoppen, zu einem bestimmten Zeitpunkt, basierend auf den Fehlern, oder wenn es einen besseren Weg gibt, um die Struktur dieser um irgendeine form der Verzweigung Verhalten, wie es der Fall ist, dass if X do Y else Z
.
Jede Hilfe wäre toll.
InformationsquelleAutor der Frage Grofit | 2014-09-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dieses Verhalten ist genau wie ein synchrones werfen:
Das ist die Hälfte der Punkt
.catch
- in der Lage sein sich zu erholen von Fehlern. Es könnte wünschenswert sein, um rethrow signal der Staat ist immer noch ein Fehler:Aber das allein wird nicht funktionieren, in deinem Fall, da der Fehler abgefangen werden, durch einen später-handler. Das eigentliche Problem hier ist, dass generalisierte "NICHTS Anfassen" Fehler-Handler sind eine schlechte Praxis im Allgemeinen und sind extrem verpönt, in anderen Programmier-Sprachen und ökosysteme. Aus diesem Grund Bluebird bietet eingetippt und Prädikat Fänge.
Den zusätzlichen Vorteil, dass Sie Ihre business-Logik nicht (und sollte nicht) wissen, das request/response-Zyklus überhaupt. Es ist nicht die Abfrage in der Verantwortung zu entscheiden, welcher HTTP status-und Fehler-der Kunde bekommt und später, wie Ihre app wächst, möchten Sie vielleicht die Trennung der business-Logik (wie Abfrage von DB und Verarbeitung Ihrer Daten) von dem, was Sie an den client senden (was http-status-code, was text und was für eine Antwort).
Hier ist, wie ich den code schreiben.
Zuerst, ich würde zu bekommen
.Query
zu werfenNoSuchAccountError
ich würde Unterklasse es ausPromise.OperationalError
die Bluebird schon bietet. Wenn Sie unsicher sind, wie um eine Unterklasse ein Fehler lass es mich wissen.Ich würde zusätzlich Unterklasse es für
AuthenticationError
tun, und dann etwas wie:Wie Sie sehen, es ist sehr sauber und man kann den text Lesen wie eine Bedienungsanleitung von dem, was passiert in den Prozess. Es ist auch getrennt von der Anfrage/Antwort.
Nun, würde ich es nennen, von der route-handler wie folgt:
Diese Weise die Logik ist alles an einem Ort und die Entscheidung, wie man Fehler behandelt, die für den Kunden alles an einem Ort, und Sie nicht in Unordnung zu trennen.
InformationsquelleAutor der Antwort Benjamin Gruenbaum
.catch
funktioniert wie dietry-catch
- Anweisung, das heißt, Sie brauchen nur einen Haken am Ende:InformationsquelleAutor der Antwort Esailija
Nicht. Sie können nicht wirklich "Ende" einer Kette, es sei denn, Sie werfen eine Ausnahme, die Blasen bis zu seinem Ende. Sehen Benjamin Gruenbaum Antwort für wie das zu tun.
Herleitung von seinem Muster wäre nicht zu unterscheiden, Fehler-Arten, jedoch nutzen, Fehler, die
statusCode
undbody
Felder, die gesendet werden können, von einem einzigen, generische.catch
handler. Je nach Anwendung, Struktur, seine Lösung könnte sauberer sein aber.Ja, Sie tun können,Verzweigung mit dem Versprechen. Dies bedeutet jedoch, lassen die Kette und "zurück" zu verschachteln - wie würde Sie in einer verschachtelten if-else oder try-catch-Anweisung:
InformationsquelleAutor der Antwort Bergi
Ich mache auf diese Weise:
Verlassen Sie Ihren Fang am Ende. Und werfen einen Fehler, wenn es passiert, midway Ihre Kette.
Ihre anderen Funktionen würde wahrscheinlich so Aussehen:
InformationsquelleAutor der Antwort Leo Leao
Statt
.then().catch()...
Sie tun können.then(resolveFunc, rejectFunc)
. Dieses Versprechen Kette wäre besser, wenn Sie behandelt Dinge auf dem Weg. Hier ist, wie würde ich umschreiben:Hinweis: Das
if (error != null)
ist ein bisschen ein hack, um die Interaktion mit den letzten Fehler.InformationsquelleAutor der Antwort mvndaai