‫Kursleiter: In dieser Vorlesung implementieren wir eine bessere
‫Methode zum Abfangen von Fehlern in all unseren asynchronen Funktionen.
‫Im Moment haben wir also
‫in all unseren asynchronen Funktionen diese try-Catch-Blöcke, oder?
‫Denken Sie also daran, wie wir all diesen Handle-Funktionen diesen try-
‫und dann diesen catch-Block hinzugefügt haben, okay?
‫Und das haben sie alle, weil es
‫sich bei allen um asynchrone Funktionen handelt,
‫und so fangen wir normalerweise die Fehler innerhalb
‫einer asynchronen Funktion ab.
‫Verwenden Sie also einen try-catch-Block.
‫Das lässt unseren Code nun wirklich unordentlich und unkonzentriert aussehen, so
‫dass das Ziel dieser createTour-Methode hier beispielsweise darin besteht,
‫diesen Code einfach auszuführen.
‫Wir wollen hier eigentlich nicht
‫mit der Fehlerbehandlung
‫herumspielen, also haben wir im Moment diese zwei zusätzlichen
‫Blöcke, try and catch, und damit
‫kommt diese zusätzliche Einrückung hier und
‫so wieder, dies lässt unseren Code wirklich nicht sauber aussehen.
‫Es ist wirklich nicht fokussiert.
‫Außerdem haben wir hier viel doppelten Code,
‫da wir in jedem
‫dieser Handler einen ziemlich ähnlichen catch-Block haben.
‫Alles, was wir bei all
‫dem tun, ist, diese Antwort zu senden.
‫Und diese Antwort würde tatsächlich nicht einmal hierher gesendet,
‫sondern stattdessen in unserer globalen Middleware zur Fehlerbehandlung, denken Sie daran,
‫aber das ist ein anderes Thema.
‫Im Moment versuche ich
‫mich hier darauf zu konzentrieren, dass
‫diese Try-Catch-Blöcke in jeder unserer asynchronen Funktionen nicht ideal sind,
‫und lassen Sie uns nun versuchen, das zu beheben.
‫Und die Lösung besteht darin, den try-catch-Block im Grunde hier
‫herauszunehmen und in einer anderen Funktion auf eine
‫höhere Ebene zu stellen.
‫Im Grunde werden wir
‫also eine
‫Funktion erstellen und diese asynchrone Funktion dann in diese Funktion einschließen.
‫Gut?
‫Lassen Sie mich das also catchAsync nennen.
‫Also catchAsync, und ich nenne es so, weil
‫das Ziel dieser Funktion
‫darin besteht, einfach unsere asynchronen Fehler abzufangen.
‫So einfach, oder?
‫In diese catchAsync-Funktion
‫werden wir also eine Funktion übergeben, okay?
‫Und denken Sie daran, die Funktion, die wir übergeben
‫werden, ist im Grunde diese.
‫Nun, da wir mit diesem Beispiel
‫arbeiten, ist die Funktion, die wir an catchAsync übergeben,
‫diese Funktion, da wir hier die
‫asynchronen Fehler abfangen möchten.
‫Also lass uns das tatsächlich tun.
‫Also fn, und packen Sie dann die gesamte Funktion dort ein.
‫Als nächstes müssen wir diese
‫Funktion hier tatsächlich aufrufen.
‫Rufen Sie es also auf, und diese
‫Funktion sollte eine Anfrage, eine Antwort und tatsächlich auch als nächstes erhalten.
‫Dieser hier sollte also eigentlich auch next haben und
‫alle anderen
‫auch, denn denken Sie daran, wir
‫brauchen die next-Funktion, um den Fehler
‫hineinzureichen, damit dieser Fehler dann
‫in der globalen Fehlerbehandlungs-Middleware behandelt werden kann.
‫Alle diese Funktionen benötigen also eine Anfrage,
‫eine Antwort und so weiter.
‫Aber lassen wir das für später.
‫Konzentrieren wir uns hier vorerst wirklich auf unser catchAsync.
‫Diese Funktion hier, die wir an async übergeben haben,
‫die jetzt hier oben fn heißt, ist
‫also eine asynchrone Funktion.
‫Und denken Sie daran,
‫dass asynchrone Funktionen Versprechen zurückgeben, oder?
‫Und wenn innerhalb einer asynchronen Funktion ein
‫Fehler auftritt, bedeutet dies im Grunde, dass die Zusage abgelehnt wird.
‫Und hier oben, wo wir diese Funktion tatsächlich aufrufen, können
‫wir dann diesen Fehler abfangen.
‫Also fangen wir es hier
‫ab, anstatt es im try-catch-Block zu fangen.
‫Also catch und error und dann weiter und übergeben Sie den Fehler.
‫Und wir
‫können dies vereinfachen, aber jetzt entfernen wir den try-catch-Block
‫hier und konzentrieren uns einfach auf dieses Stück.
‫Das ist also
‫alles, was wir wollen, und wir brauchen den try-catch-Block
‫nicht mehr, weil dieser Catch jetzt im Grunde hierher übertragen
‫wird, in diese Zeile.
‫Es ist kein Catch-Block
‫mehr, weil es hier einfach einfacher
‫ist, das Versprechen zu verwenden, dass die fn-Funktion zurückgibt.
‫Diese fn-Funktion ist also wieder diese Funktion, also diejenige,
‫die wir an catchAsync übergeben haben, und
‫die wird ein Versprechen zurückgeben.
‫Und tatsächlich ist mir hier aufgefallen,
‫dass das natürlich catchAsync heißen sollte, in Ordnung?
‫Und dann ist diese
‫Funktion, die wir an catchAsync übergeben haben, natürlich fn.
‫Gut?
‫Also das Argument, das wir da reingereicht haben.
‫Nun, es gibt tatsächlich zwei große Probleme mit
‫der Art und Weise, wie dies derzeit
‫implementiert wird, und so würde es überhaupt nicht funktionieren.
‫Der erste Funktionsaufruf hier
‫hat also keine Möglichkeit, Anforderung, Antwort und Nächstes zu kennen.
‫Wir haben sie hier nicht an catchAsync übergeben,
‫und daher hat die
‫Funktion keine Möglichkeit, die Werte dieser Parameter zu kennen.
‫Und zweitens rufen wir
‫hier tatsächlich die asynchrone Funktion auf.
‫Und um dies ein bisschen besser zu sehen, lassen
‫Sie uns diesen Code einfach vollständig loswerden.
‫Hier haben wir also catchAsync und rufen es dann natürlich
‫mit den Klammern auf.
‫Und dann rufen wir innerhalb von catchAsync
‫dann auch gleich die fn-Funktion auf, und
‫so soll das nicht funktionieren.
‫CreateTour sollte hier also eigentlich eine Funktion sein,
‫aber nicht das Ergebnis eines Funktionsaufrufs.
‫Aber genau das passiert gerade.
‫Im Moment wird also
‫catchAsync aufgerufen, das dann diese Funktion hier aufruft, okay?
‫Diese Funktion sollte also nicht aufgerufen
‫werden, sondern hier sitzen und warten,
‫bis Express sie aufruft.
‫Und Express ruft
‫es natürlich an, sobald jemand
‫den Weg einschlägt, der diese Kontrollfunktion benötigt.
‫Die Lösung dafür besteht also darin, die catchAsync-Funktion im
‫Grunde eine andere Funktion zurückgeben zu lassen, die
‫dann createTour zugewiesen wird und diese Funktion
‫dann später bei
‫Bedarf aufgerufen werden kann.
‫Also machen wir das hier.
‫Geben wir also eine anonyme Funktion zurück und
‫denken Sie daran, dass dies die Funktion
‫ist, die Express dann aufruft.
‫Hier spezifizieren wir
‫dann Anfrage, Antwort und Weiter.
‫Hier fehlt tatsächlich der Pfeil.
‫Und alles klar.
‫Und das ist es tatsächlich.
‫Das ist unsere catchAsync-Funktion.
‫Denken Sie daran, wie ich
‫gesagt habe, dass wir es vereinfachen können,
‫und das nur, weil wir es in
‫JavaScript so vereinfachen können, dass wir hier nur die
‫Funktion übergeben müssen, und sie wird dann
‫automatisch mit dem Parameter aufgerufen, den dieser Callback empfängt.
‫Es ist also dasselbe wie beim nächsten Schreiben.
‫Fassen wir also hier zusammen.
‫Um unsere try-catch-Blöcke loszuwerden, haben
‫wir unsere asynchrone Funktion
‫einfach in die soeben erstellte catchAsync-Funktion eingebettet.
‫Diese Funktion gibt dann eine neue anonyme
‫Funktion zurück,
‫nämlich diese hier, die dann createTour zugewiesen wird.
‫Im Grunde ist es diese
‫Funktion hier, die aufgerufen wird, sobald eine
‫neue Tour mit dem createTour-Handler erstellt werden soll.
‫Aus diesem Grund hat es hier genau
‫dieselbe Signatur wie diese asynchrone Funktion, mit Anfrage, Antwort und Weiter.
‫Diese Funktion hier wird nun
‫die Funktion aufrufen, die
‫wir ursprünglich übergeben haben, also
‫diese hier,
‫und dann den gesamten darin enthaltenen Code ausführen.
‫Da es sich hier um eine
‫asynchrone Funktion handelt,
‫gibt sie ein Promise zurück. Wenn also in diesem
‫Promise ein Fehler auftritt oder mit anderen
‫Worten, falls es abgelehnt wird, können wir
‫den aufgetretenen Fehler mit der catch-Methode abfangen auf alle Versprechen verfügbar.
‫Und am Ende ist es diese Catch-Methode
‫hier, die den Fehler an die nächste Funktion
‫weiterleitet, die es dann so
‫macht, dass unser Fehler in unserer globalen Fehlerbehandlungs-Middleware landet.
‫Hier, in dieser Codezeile, passiert also
‫wirklich die ganze Magie, und das ist
‫es tatsächlich, was es
‫uns ermöglicht, den Catch-Block loszuwerden, den wir zuvor hatten.
‫Und eine
‫Anmerkung: Es ist ziemlich kompliziert, den Kopf zu drehen,
‫und falls es nicht 100% klar ist, keine
‫Sorge, es ist nicht so wichtig.
‫Hier geht es wirklich nur darum herauszufinden, wie
‫genau asynchroner Code hinter den Kulissen in JavaScript funktioniert.
‫Es geht also nicht so sehr um Express oder Node. js, hier geht
‫es mehr um die Funktionsweise von asynchronem Code.
‫Wie auch immer, wenn wir jetzt
‫eine neue
‫Tour erstellen und ein Fehler
‫auftritt, zum Beispiel durch eine ungültige Eingabe,
‫dann sollte dieser Fehler
‫natürlich hier in dieser Fangfunktion abgefangen werden und
‫wird dann an unsere Fehlerbehandlungs-Middleware weitergegeben und damit one
‫sendet dann die erwartete Fehlerantwort zurück.
‫Und das probieren wir jetzt mal aus.
‫Erstellen Sie also eine neue Tour.
‫Hier haben wir den
‫Körper, und lassen Sie uns nun eines dieser erforderlichen Felder loswerden.
‫Gut.
‫Das sollte also einen Fehler auslösen, also mal sehen.
‫Und tatsächlich ist unsere Tourvalidierung fehlgeschlagen, was genau
‫die Fehlermeldung ist,
‫die wir erhalten sollten.
‫Hier sehen Sie nun diesen 500 Internal Server Error, der
‫einfach darauf zurückzuführen ist, dass für
‫den Fehler, der an
‫die Fehlerbehandlungs-Middleware weitergegeben
‫wurde, kein Statuscode angegeben wurde. Denken Sie
‫also daran, dass unser Standardwert 500 ist,
‫und das ist es das wurde dann zurückgeschickt.
‫Und das müssen wir natürlich korrigieren,
‫und das werden wir in einer späteren Vorlesung in diesem Kurs tun.
‫Im Moment ist es wichtig,
‫dass unsere Funktion catchAsync wie beabsichtigt funktioniert und zweitens
‫der Fehler tatsächlich weitergegeben wurde, sodass er von
‫unserer globalen Middleware zur Fehlerbehandlung abgefangen wurde,
‫die diese Antwort dann an den Client zurücksendete.
‫Lassen Sie uns nun diese Fangfunktion
‫in eine eigene Datei exportieren.
‫Also greife ich es von
‫hier und erstelle nur eine weitere
‫Datei in unserem Dienstprogrammordner.
‫Also catchAsync. js.
‫Und hier, Modul. Exporte sollten genau das sein.
‫Und damit sollte das problemlos funktionieren.
‫Zurück in unserem Tourcontroller müssen
‫wir diese Funktion nun natürlich importieren.
‫Und wie üblich müssen wir einen Ordner
‫nach oben gehen und dann in unseren
‫Dienstprogramme-Ordner und dann catchAsync.
‫Alles klar, und
‫jetzt müssen wir nur noch all
‫diese catch-Blöcke loswerden und alle Handler in catchAsync einschließen.
‫Also machen wir das.
‫Führen Sie zuerst die Verpackung durch und entfernen Sie dann diese Blöcke.
‫Speichern Sie es, um es neu zu formatieren, und los geht's.
‫Und jetzt ist es einfach ein Prozess,
‫dies zu wiederholen, bis alle Touren oder, sorry,
‫bis alle Handler fertig sind.
‫Okay, schnell speichern.
‫Dieser ist bereits fertig.
‫Als nächstes steht ein Update an.
‫Und nur noch einer fehlt.
‫Oder eigentlich stimmt das nicht.
‫Da unten haben wir noch mehr Async-Funktionen.
‫Also werden wir den Fang und den Versuch hier los.
‫Und ich glaube, dieser ist der letzte.
‫Und ja, das ist es tatsächlich.
‫In Ordnung, jetzt müssen
‫wir auch noch neben allen hier hinzufügen.
‫Aber natürlich nicht in Großbuchstaben.
‫Okay.
‫Und lassen Sie mich hier eigentlich alle auswählen,
‫damit ich es nur einmal schreiben muss.
‫Und das fügte es allen hinzu.
‫Und jetzt denke ich, dass wir mit diesem Teil fertig sind.
‫Lass es uns noch einmal ganz schnell testen, nicht
‫mit diesem, aber hier mit, auch nicht mit
‫diesem, also sind wir fertig.
‫Und ich werde versuchen, eine
‫Tour zu bekommen, aber mit einem ungültigen Ausweis, also mal sehen, was hier passiert.
‫Und tatsächlich bekommen wir unsere Fehlermeldung und
‫wieder den 500er Statuscode, was nicht korrekt
‫ist, denk dran, aber
‫darum kümmern wir
‫uns zu einem späteren Zeitpunkt.
‫Lassen Sie mich Ihnen jetzt zeigen, dass
‫hier die 500 herkommen, denn im Moment gibt es keinen Statuscode
‫in dem Fehler, den wir
‫erhalten, weil diese Fehler
‫tatsächlich von Mungo kommen und wir daher keine
‫Möglichkeit haben, einen
‫Status hinzuzufügen Code für diese Fehler.
‫Oder wir könnten es natürlich auch tun, aber das
‫wäre nur noch verwirrender und deshalb werden
‫wir später in diesem Abschnitt einen anderen
‫Weg finden.
‫Im Moment bin ich sehr zufrieden mit dem Ergebnis, das wir
‫hier haben, und das war's für diesen Vortrag.