‫Jonas: In diesem Video
‫implementieren wir eine Logik, um verschiedene Fehlermeldungen
‫für die Entwicklungs- und Produktionsumgebung zu senden.
‫Im Moment senden wir hier im Grunde die gleiche Antwortnachricht an
‫alle, egal ob wir uns in der Entwicklung oder
‫in der Produktion befinden.
‫Aber die Idee ist, dass wir in der Produktion so
‫wenig Informationen wie möglich über unsere Fehler
‫an den Kunden weitergeben wollen.
‫In diesem Fall möchten wir also
‫nur eine nette, menschenfreundliche Nachricht
‫senden, damit der Benutzer weiß, was nicht stimmt.
‫Auf der anderen Seite
‫möchten wir bei der schriftlichen Entwicklung so viele Informationen
‫wie möglich über den aufgetretenen Fehler erhalten, und
‫zwar direkt in der Fehlermeldung, die zurückkommt.
‫Wir könnten diese Informationen also auch in der
‫Konsole protokollieren, aber ich denke, es ist in diesem Fall
‫viel nützlicher, diese Informationen direkt im Postboten zu haben.
‫Wir wissen also bereits, wie man zwischen
‫der Entwicklungs- und der Produktionsumgebung unterscheidet.
‫Also, lass uns das tun.
‫Also
‫wenn Prozess. env. node_env ist
‫gleich development, dann möchten wir
‫einen Fehlertyp senden und
‫wenn wir in
‫der Produktion sind, möchten wir einen einfacheren Fehler senden.
‫In Ordung.
‫Also gleich der Produktion.
‫Okay, greifen wir also zu diesem hier,
‫also wollen wir bei
‫der schriftlichen Entwicklung alle Informationen erhalten, die wir können.
‫Also auch hier mit dem Fehlerstack drucken oder antworten.
‫Also irr. stack, und dann drucken
‫wir auch den gesamten Fehler.
‫Sagen wir Fehler und stellen Sie es in Ordnung.
‫Andererseits kopieren
‫wir das jetzt noch einmal.
‫Wenn wir in der Produktion sind, wollen wir
‫weder den Stack noch den kompletten Fehler.
‫Also eigentlich nur der Status und die Nachricht.
‫Das hier sieht irgendwie
‫chaotisch aus, also exportieren wir diese in
‫ihre eigenen Funktionen und auch weil wir hier
‫unten in diesem else-Zweig viel mehr Code hinzufügen werden.
‫Es ist ein bisschen sauberer, diese in ihre eigenen
‫separaten Funktionen zu integrieren.
‫Nehmen wir
‫also an, const send error
‫for dev und diese Funktion sollte dann
‫den Fehler erhalten, und wir müssen auch den Antwortbetreff übergeben.
‫Das liegt daran, dass wir die Antwort
‫tatsächlich so senden können, oder?
‫Wir benötigen also das Antwortsubjekt, um diesen Code ausführen
‫zu können.
‫Hier rufen wir nur send
‫error dev mit
‫dem Fehler
‫und der Antwort auf.
‫Dann müssen
‫wir
‫hier unten eine Fehlerproduktion senden, die
‫gleichen Argumente.
‫Und dann hier das gleiche.
‫Das war also einfach, lassen Sie uns jetzt auf die nächste
‫Ebene gehen und noch einmal über Betriebsfehler sprechen.
‫Lassen Sie mich dazu die von uns erstellte
‫App-Fehlerklasse öffnen und daran erinnern, dass wir
‫alle Fehler, die
‫wir erstellen, markieren, indem AppError ist operational auf true gesetzt ist.
‫Alle Fehler, die wir
‫selbst erstellen, sind also grundsätzlich Betriebsfehler.
‫Tatsächlich sind es nur diese Betriebsfehler, bei
‫denen wir die Fehlermeldung an den Client
‫senden möchten.
‫Zumindest in der Produktion.
‫Wenn wir hingegen einen Programmierfehler oder einen anderen
‫unbekannten Fehler haben, der
‫beispielsweise von einem Drittanbieterpaket stammt, möchten
‫wir keine Fehlermeldung darüber an den Kunden in
‫der Produktion senden.
‫Und das nützt also nichts.
‫Dies ist Betriebseigenschaft hier in unserem Fehlercontroller.
‫Erinnern Sie sich, wie ich bereits
‫darüber gesprochen habe, als wir diese Klasse erstellt haben, richtig?
‫Lassen Sie uns jetzt hierher kommen, um die Fehlerproduktion zu senden
‫und diesen Test durchzuführen.
‫Wenn Fehler. isOperational nur
‫in diesem Fall wollen wir diesen Fehler eigentlich hierher schicken.
‫In allen
‫anderen Fällen senden
‫wir einfach eine sehr allgemeine Fehlermeldung an den Client.
‫Sagen wir also, res. status und wir
‫senden einfach einen generischen 500-Code und
‫dann json.
‫Der Status wird Fehler sein.
‫Dann lassen Sie uns einfach eine allgemeine Nachricht senden und sagen,
‫dass etwas
‫sehr schief gelaufen ist.
‫So etwas zu tun ist also ein ganz normales Verfahren.
‫Lassen Sie mich hier einen Teil des Codes auskommentieren.
‫Dies ist also ein Betriebsfehler, dem wir vertrauen.
‫Hier möchten wir eine Nachricht an den Client senden.
‫Aber in diesem
‫Fall haben wir hier einen unbekannten
‫Fehler, und deshalb möchten wir die Details nicht an den Kunden weitergeben.
‫Also werden wir diese Nachricht dann einfach an den Kunden und
‫auch für uns selbst senden.
‫Für uns Entwickler möchten wir
‫wissen, dass dieser seltsame, unerwartete, unbekannte Fehler aufgetreten ist,
‫und wir werden ihn tatsächlich in der Konsole protokollieren.
‫Wir protokollieren zuerst
‫den Fehler und senden dann eine allgemeine Nachricht.
‫Sagen wir einfach, Konsole. Fehler, also ist dies ein bisschen
‫wie eine Konsole. log, aber
‫es ist wirklich spezifisch für Fehler und
‫ich glaube, die Ausgabe sieht dann etwas anders aus.
‫Also Fehler, fügen wir hier einige Emojis hinzu, um sie in unseren
‫Protokollen sichtbar
‫zu machen, und protokollieren Sie dann auch den Fehler.
‫Jetzt gibt es echte Logging-Bibliotheken auf mpm, die wir hier
‫verwenden könnten, anstatt
‫nur diese einfache Konsole zu haben. Fehler, aber nur das
‫Protokollieren des Fehlers in der Konsole macht
‫ihn in den Protokollen auf
‫der von Ihnen verwendeten Hosting-Plattform sichtbar.
‫Ich denke, das reicht bei dieser einfachen Anwendung für den
‫Moment aus.
‫Zum Beispiel werden wir Heroku
‫am Ende des Kurses verwenden, um unsere Anwendung bereitzustellen.
‫Wenn dann ein solcher Fehler
‫auftritt, wird er in der Konsole protokolliert.
‫Auf der Heroku-Plattform haben wir dann Zugriff auf diese Protokolle.
‫Wir können uns diese Protokolle weiter ansehen und dann
‫dort diese unerwarteten Fehler finden, um
‫sie dann zu beheben.
‫Im Moment bauen wir hier tatsächlich
‫bereits eine Art ausgeklügelter und
‫realitätsnaher Fehlerbehandlungsmechanismus.
‫Fassen wir also kurz zusammen, was wir hier gerade gemacht haben.
‫Wir unterscheiden zwischen Fehlern in der Entwicklung und in
‫der Produktion.
‫Wenn wir in der Produktion sind, senden
‫wir den Fehler mit
‫dieser Funktion hier, die dann so viele Details wie
‫möglich an
‫den Client sendet, damit wir
‫wirklich alle Informationen erhalten, um den Fehler loszuwerden.
‫Wenn es sich um
‫einen Programmierfehler oder einen Betriebsfehler handelt,
‫möchten wir trotzdem wirklich alles sehen, was vor sich geht.
‫Wenn wir in
‫der Produktion sind, was wohl der
‫wichtigste Teil unserer Anwendung ist, dann unterscheiden wir
‫zwischen Betriebsfehlern, also Fehlern,
‫die wir kennen und denen wir
‫vertrauen, und anderen Fehlern, die irgendwie unerwartet sein können.
‫Wenn der Fehler betriebsbereit ist, also beispielsweise der Benutzer
‫versucht hat, auf eine nicht vorhandene Route zuzugreifen,
‫oder versucht hat, ungültige Daten einzugeben,
‫sind dies alle Betriebsfehler.
‫Dann können wir entsprechende Fehlermeldungen senden, damit der
‫Kunde weiß, was schief gelaufen ist.
‫Auf der anderen Seite haben wir diese unbekannten Fehler
‫oder unerwarteten Fehler, und in diesem Fall
‫sagen wir ganz einfach, dass etwas schief gelaufen ist.
‫Dann loggen Sie den Fehler auch in unsere Konsole
‫ein, damit wir wissen, dass er aufgetreten ist und ihn dann beheben können.
‫Damit dies funktioniert, müssen
‫wir etwas wirklich, wirklich Wichtiges
‫tun.
‫Im Moment gibt es Fehler, die
‫zum Beispiel von MongoDB kommen, die wir nicht als betriebsbereit markieren.
‫In diesem Fall würden sie jetzt einfach mit
‫dieser generischen Fehlermeldung hier behandelt.
‫Zum Beispiel ein Validierungsfehler.
‫Im Moment ist das ein Fehler, der
‫von MongoDB kommt und nicht von unserer eigenen App-Fehlerklasse.
‫Wir erstellen diese Fehler nicht selbst.
‫Auch hier sind sie im Moment noch nicht als betriebsbereit markiert,
‫aber wir müssen sie natürlich als betriebsbereit markieren, damit
‫wir dann die entsprechende Fehlermeldung an
‫den Client zurücksenden können.
‫In dem gerade erwähnten Beispiel
‫sind die Eingabedaten ungültig.
‫Es gibt noch zwei oder drei weitere Fehler, die wir
‫selbst als funktionsfähig markieren müssen.
‫Also werden wir
‫das hier unten tun.
‫In diesem else-Block werden
‫wir das in den nächsten Vorlesungen tun.