Alle Folgen

Webcafé — Folge 6

Keine Angst vor Exceptions

Wir sprechen heute über Fehler, Errors und Exceptions im Code.

hören lesen

Folge 6 Keine Angst vor Exceptions 26 min · 13 Kapitel
0:00 25:48

Am Mikrofon

01 — Worum geht es

Worum geht es?

Wir sprechen heute über Fehler, Errors und Exceptions im Code.
Anhand eines Praxisbeispiels erörtern wir, wie gezielt geworfene Fehler zum eigenen Vorteil genutzt werden können und zeigen auf, dass Fehler nicht immer unterdrückt oder abgefangen werden sollten.
Wir beschreiben was einen guten Fehler ausmacht und wie man von Fehlern in der eigenen Anwendung mitbekommt.
Außerdem sprechen wir über ein sinnvolles Error-Handling - sowohl für Entwickelnde als auch für die Nutzenden.

02 — Transkript

Das Gespräch, Wort für Wort

Kapitel

4.344 Wörter in 12 Abschnitten. Jede Zeitmarke springt an die passende Stelle im Audio. Automatisch transkribiert und maschinell nachkorrigiert — im Zweifel gilt das Gesprochene.

Begrüßung 0:00–1:37

  1. 0:00

    Herzlich willkommen zu einer neuen Folge vom Webcafé und ich freue mich, dass mir auch heute wieder virtuell unser Technik-Elied, der Kay, gegenüber sitzt.

  2. 0:14

    Hallo Felix, ich freue mich auch und auch hallo an die lieben Leute da draußen. Wir sind beide bei der GNT-Systeme GmbH in Dortmund angestellt, wo ich als Geschäftsführer arbeite. Und Kay, das Allerwichtigste natürlich zuerst, welches Getränk hast du dir mitgebracht? Gut, dass du fragst. Ich habe heute ein kleines Mitmach-Experiment, also ein imaginäres Mitmach-Experiment. Und zwar habe ich hier einen orientalischen Chai-Tee stehen, der gerade aufbrüht. Und daneben aus meiner Siebträgermaschine ein frisches Kännchen aufgeschäumte Milch. Und jetzt werde ich das mal hier hineinführen und dann sehen wir, wie das so schön Wolken wirft unten.

  3. 0:54

    Und jetzt habe ich hier so eine schöne Kombination. Ich hoffe, ihr könnt euch das alle bildlich vorstellen und es riechen und schmecken. Chai-Tee ist ja über den Winter auch einer meiner Lieblingstees. Für mich bin ich schon so ein bisschen aus der Jahreszeit raus. Ich habe mir einen Kluntje-Tee mitgebracht. Und zwar ist das so ein Schwarz-Tee, der dann mit so Zuckerstückchen, mit diesen Kluntjes, Kandes-Zucker auch genannt, verfeinert wird. Und dann ein Schuss Milch rein. Ist für mich ein richtiger Traum. War lange Zeit mein Lieblingstee, bis er abgelöst wurde durch so einen Eierlikör-Tee, der einfach genial ist.

  4. 1:27

    Den werde ich irgendwann anders mal mitbringen. Ist gerade leer. Mein Experiment hier ist übrigens ganz großartig cremig im Mund. Das wollte ich nochmal nachreichen. Freut mich sehr. Wir haben eine kleine Korrektur zu Beginn. Wir haben nämlich in der letzten Folge von CDC-Tests gesprochen. Und da haben wir gesagt, dass das Customer-Driven-Contract-Tests sind. Das ist aber nicht korrekt. Es sind nämlich Consumer-Driven-Contract-Tests. Und das wollen wir ja einmal kurz klarstellen. Nicht, dass das jemand falsch weitergibt. Das Prinzip, was wir erklärt haben, ist aber dann das Gleiche dahinter. Jetzt kommen wir zum eigentlichen Thema.

Einleitung ins Thema 2:01–4:08

  1. 2:04

    Und Kay, ich bringe ja gerne eine kleine Einstiegsfrage mit. Und die lautet heute, ob du weißt, was am 4. Juni 1996 passiert ist. Am 4. Juni 1906 und um Himmels Willen. Also, ich könnte dir vielleicht was aus meinem persönlichen Leben sagen. Aber wahrscheinlich willst du darauf nicht hinaus. Am 4. Juni 1996 ist die Ariane 5-Rakete gestartet. Und das hat nicht so wahnsinnig lange gedauert. Die ist nämlich nur ungefähr 40 Sekunden in der Luft gewesen. Und dann ist sie explodiert. Was da passiert ist, wir haben heute ja das Thema Errors, Exceptions, Exception-Handling. Kannst du dir vorstellen, was da los war?

  2. 2:47

    Ja, wenn man so ein bisschen Mathe interessiert ist, dann kennt man die Geschichte natürlich. Ich hoffe, ich verwechsel die jetzt nicht. War das nicht irgendein Umrechnungsfehler? Oh, Kay, das hätte ich jetzt wirklich nicht gedacht. Du überraschst mich. Ja, es war eine Umwandlung von einer Float-Zahl in einen Integer. Und das hat zu einem Overflow geführt. Und das Ganze war eben eine Unhandled Exception. Das war ein Code, der von der alten Ariane 4-Rakete übernommen wurde. Das war ja hier die erste Ariane 5, die gestartet wurde. Und damit gingen dann vier Forschungssatelliten und ein paar Millionchen in die Luft.

  3. 3:22

    Und das finde ich eigentlich ein ganz cooles Beispiel, warum Fehler und Exceptions, Errors in der Vergangenheit so ein schlechtes Image hatten.

  4. 3:30

    Und vielleicht sogar auch bis heute. Und die Sichtweise wollen wir heute so ein bisschen widerlegen, weil Errors eigentlich ganz cool sind. Man kann mit Exceptions super arbeiten. Man muss nur wissen, wie man es macht und man muss es richtig machen. Genau. Errors und Exceptions vielleicht, wir benutzen das, glaube ich, synonym. Auch wenn es da von TechStack zu TechStack feine Unterschiede gibt. Aber, wie du es richtig sagst, das Thema heute, das habe ich wieder direkt aus meinem Alltag entnommen, Arbeitsalltag.

  5. 4:00

    Und zwar nehme ich das auch gleich als Beispiel. Oder soll ich direkt einsteigen? Wir können direkt loslegen eigentlich, ne? Ja, fangen wir mit dem Praxisbeispiel an. Das ist das Beste, was wir machen können. Großartig. Also ich habe einen Merge-Request gesichtet von einem Kollegen. Und wir haben da so eine Frontend-Anwendung gebaut, also eine Webseite im Wesentlichen. Und da gab es eine Navigationsleiste. Und irgendwo im Code hat der Kollege dann diese Navigationsleiste konfiguriert und ein Array gemacht. Und jeder Eintrag in diesem Array hatte ein Label und einen Pfad, also einen URL-Pfad. Und aus dieser Konfiguration wurde dann nachher an einer ganz anderen Stelle in der Anwendung das tatsächliche UI zusammengebaut.

Praxisbeispiel 4:08–6:17

  1. 4:41

    Also das kann man sich, glaube ich, gut vorstellen. Ich versuche das mal möglichst bildlich zu beschreiben. Und dann wurde das so durch verschiedene Komponenten und auch durch externe Bibliotheken geschleucht, dieses Konfigurations-Array. Und am Ende, da wo es dann wirklich ins UI umgebaut wurde, konnte es nun sein, anhand der Typisierung,

  2. 5:02

    dass dieser URL-Pfad im Item nicht da ist. Obwohl wir ihn vorher an einer anderen Stelle konfiguriert haben, durch die Typisierung, auch durch externe Pakete, die wir benutzen, war der nicht da. Und was hat der Kollege gemacht in seinem Array, in seinem Merge-Request, um der Typisierung zu genügen auch, hat der da als Default einen leeren String gesetzt. Also das Item wurde gerendert mit entweder der URL aus der Konfiguration oder einem leeren String, wenn das nicht da ist.

  3. 5:34

    Und die Frage war jetzt, war das so richtig und wie gehen wir damit um? Und vielleicht leite ich das an dich weiter, Felix. Das ist ein bisschen suggestiv im Rahmen dieser Folge. Also das Problem, was hier natürlich entsteht, ist, dass wir eigentlich eine fehlerhafte Konfiguration, nenne ich es jetzt mal, haben

  4. 5:54

    und das aber nicht merken, bis vielleicht mal irgendein Kunde draufklickt, kein Ergebnis kriegt und das bestenfalls noch irgendwie an uns zurückmeldet.

  5. 6:03

    Schöner wäre natürlich, so nach diesem Fail-Loudly-Prinzip, wenn wir direkt beim ersten Mal auch schon merken, oh, da ist irgendwas nicht richtig konfiguriert, da läuft irgendwas schief und das dann bestenfalls auch beheben können. Geht das in die Richtung von deiner Idee? Ja, genau. Was der Kollege hier gemacht hat, das war vielleicht ein bisschen kurzsichtig. Und zwar hat er jetzt irgendwie an dieser Stelle auf Biegen und Brechen versucht, der Typisierung Genüge zu tun, die ja dafür da ist, um darauf hinzuweisen, dass hier irgendwas komisch ist in der Anwendung. Und so wie er das jetzt gelöst hat, nämlich mit diesem leeren String als Default, hat er zwar der Typisierung Genüge getan,

Gefahr von verdeckten Fehlern 6:17–9:34

  1. 6:42

    aber der hat das ursprüngliche Problem damit nur verschoben. Und zwar das Problem, dass wenn dieser Zustand eintritt, nämlich dass aus irgendeinem Grund da keine URL definiert ist,

  2. 6:56

    dass dann irgendetwas super Merkwürdiges passiert ist und die Anwendung in einem Zustand ist, in der sie eigentlich nicht sein dürfte. Also eine total unmögliche Situation, möchte ich sagen. Und dadurch, dass er das mit so einem Default überspielt, geht diese Information an uns verloren.

  3. 7:17

    Aber gleichzeitig wird dadurch die Anwendung in so einem metaphorischen Sinne ja nicht von dem Problem befreit, dass es keine URL für diesen Navigationspunkt kennt, sondern es wird dann einfach ein leerer String angezeigt. Und der Fehler entsteht dann nicht bei uns im Code, an der Stelle, wo tatsächlich auch der Fehler den Ursprung hat, sondern der Fehler entsteht dann erst drei Schritte weiter beim Anwender, indem er da draufklickt und nichts passiert. Und das ist in vielerlei Hinsicht der schlechtere Weg. Also die ursprüngliche Idee dahinter ist, wenn die Anwendung einen Zustand erreicht hat, der nicht sinnvoll ist, um damit weiterzuarbeiten,

  4. 7:57

    dann ist der einzig richtige Weg in meinen Augen, das auch durch eine harte Exception oder durch einen harten Error kenntlich zu machen.

  5. 8:05

    Zum einen im Code, also dass der Kollege dadurch so einen harten Error repräsentiert, hier stimmt irgendwas nicht. Aber auch, weil uns das total viele Möglichkeiten gibt, nachher darauf zu reagieren. Da gehen wir sicherlich noch drauf ein. Das heißt, in einem konkreten Beispiel habt ihr dann tatsächlich eine Exception oder einen Error geworfen? Oder was habt ihr dann da gemacht? So haben wir das gemacht. Wir haben einen Error geworfen an der Stelle und haben gesagt, so sinngemäß, hier ist ein Zustand, der nicht erreicht ist, der nicht sinnvoll ist, wurde hier erreicht. Und wir müssen damit umgehen. Und zwar im allerersten Schritt müssen wir das kundtun.

  6. 8:43

    Weil, wie gesagt, nur dadurch, dass man da so ein Default setzt, wird das Problem nicht aufgelöst. Es wird nur versteckt und an eine Stelle verschoben, die sehr viel weniger aussagekräftig ist. Weil, wenn es dann nachher darum geht, damit zu interagieren, ist es so, dass solche Fehler selten recovered werden können.

  7. 9:04

    Oder ich formuliere es ein bisschen anders. Es gibt zwei Arten von Fehler, die so entstehen. Die einen können recovered werden und die anderen nicht. Und meistens, wenn wir über solche Fehler sprechen, dann sind das Zustände, von denen nicht automatisch recovered werden kann und sollte, weil irgendwas ganz Grobes schiefgelaufen ist. Und dann ist so ein Error super hilfreich, weil wir damit technisch super gut umgehen können. Und das User-Feedback auch entsprechend gestalten können als einfach nur so einen leeren String. Und wir müssen hoffen, dass uns jemand anruft und sagt, dass da was nicht geht.

Fehler richtig werfen 9:34–10:15

  1. 9:35

    Das ist nämlich das Hauptproblem an dieser Geschichte, wenn man sowas verdeckt. Wir als Entwickler wollen von dem Fehler ja wissen, damit wir wissen, oh, hier ist irgendwas passiert. Wir wollen wissen, wie dieser Zustand zustande kommen konnte. Und wir wollen dann vielleicht was im Code ändern, damit dieser Fehler nicht wieder auftritt. Und davon müssen wir zunächst einmal wissen, dass der passiert. Und wenn man ihn so verdeckt, wie der Kollege das gemacht hat, dann bekommen wir damit vielleicht nur über Bande mit, aber möglicherweise auch gar nicht.

  2. 10:07

    Und so einen harten Fehler zu werfen, gibt uns ganz viele Möglichkeiten, den abzufangen, mit dem umzugehen und den dann zu reporten.

Fehler als Nutzererfahrung 10:15–12:15

  1. 10:15

    Du hast jetzt ganz viele Themen aufgemacht, zu denen ich kurz was kommentieren muss. Das erste ist so dieses Gefühl beim Kunden, wenn jetzt eine Anwendung rausgebracht wird, wo wir den Fehler behandeln, wie das ursprünglich gedacht war.

  2. 10:27

    Dann kann das sein, dass der Kunde jetzt in dem Menü, was du da gesagt hast, auf den Link klickt und da passiert nichts. Und das ist natürlich immer schlecht. Dann denkt er, hier passiert nichts, dann klickt vielleicht nochmal drauf und dann ist er verärgert. Wenn man das allerdings in einem Fehler oder in einem Fehler wirft und den im Code vernünftig abfängt, dann könnte man dem Kunden eine Fehlermeldung anzeigen und zum Beispiel sagen, hier, die Seite ist nicht verfügbar. Man könnte sogar vielleicht eine witzige Fehlermeldung reinbringen. Das finde ich mal ganz cool. Man kennt ja diese 404 Seiten im Internet, wenn eine Webseite nicht verfügbar ist oder nicht mehr verfügbar ist,

  3. 10:59

    dass dann da vielleicht so ein kleines Männchen kommt und sagt so, ich suche hier gerade noch nach der Seite und habe aber noch nichts gefunden. Dann erzeugt mir, glaube ich, ein ganz anderes Gefühl beim Kunden, der so das Gefühl hat, da ist jemand, der hat sich damit beschäftigt und das klappt jetzt gerade nicht.

  4. 11:14

    Aber ich gucke vielleicht wann anders nochmal wieder rein und dann geht es eventuell. Genau, das ist total wichtig, was du gesagt hast. Wenn man einen der beiden Aspekte des Error-Handlings betrachtet, wir wollen dem Endnutzer zeigen, dass wir mitbekommen haben, dass er was wollte, aber das irgendwie nicht geklappt hat.

  5. 11:32

    Du hast es schon gesagt, es gibt nichts Frustrierendes als irgendeine Anwendung, wo man draufklickt und es passiert nichts. Alleine, wenn dann schon so ein kleines Pop-up kommt und sagt, Fehler passiert, dann weiß der Nutzer zumindest schon mal, es hat nicht daran gelegen, dass er nicht fest genug geklickt hat, sondern die Anwendung reagiert auf seinen Input, aber es hat dann irgendwas nicht geklappt.

  6. 11:50

    Genau, aber ich bin auch kein großer Fan von Fehler 2, 3, 6, 8, 9, wo der Kunde dann wirklich gar nichts mit anfangen kann.

  7. 11:58

    Das halte ich für nicht so wahnsinnig sinnvoll. Ich bin da ein großer Fan von diesen Custom Errors, wo man dann auch eine außergekräftige Fehlerbeschreibung, Fehler-Message reinbringt, die bestenfalls sogar übersetzt ist, sodass der Kunde dann auch eine Info hat, meinetwegen, dass da was nicht erreichbar oder was auch immer da schiefgegangen sein kann. Genau, und das ist eben der starke Vorteil, wenn man die Fehler bewusst wirft, also im Code wirklich hingeht und eigene Fehler wirft,

Vorteile von eigenen Exceptions 12:15–15:19

  1. 12:23

    dass man freie Gestaltungsmöglichkeiten hat, wie dieser Fehler aussehen soll. Das heißt, unter welchem Namen der laufen soll, welche Zusatzinformationen da sinnvoll sind und wie man damit weiter umgeht. Während wenn man das einfach so verdeckt, dann überlässt man das alles dem Zufall. Und wenn man dann mit so speziellen Error-Fällen oder Error-Klassen oder verschiedenen Error-Namen hantiert, dann kann man eben sehr schön darauf basierend auf den verschiedenen Fehlerklassen eine Meldung bei dem Nutzer anzeigen,

  2. 12:54

    der ihm vielleicht auch sagt, hey, schau mal hier, das hat nicht geklappt, tut mir leid, versuch es gleich nochmal, das kennt man sicherlich, oder vielleicht auch Fehler, wo man dann proaktiv werden kann, wie zum Beispiel, wenn im Hintergrund irgendeine Session abgelaufen ist, dann wirft man einen entsprechenden Autorisierungsfehler, kann dann wiederum an irgendeiner Stelle im Error-Handling auf diesen Fehler testen und wenn der aufgetreten ist, dann zeigt man vielleicht dem Nutzer direkt so eine Maske an mit, hey, deine Session ist abgelaufen, bitte melde dich hier neu an oder sowas. Schickt ihn proaktiv auf die Login-Seite weiter.

  3. 13:26

    Das sind eben Möglichkeiten, die man hat, wenn man mit dedizierten Error-Klassen, nenne ich es mal, arbeitet,

  4. 13:35

    dass man individuelle Nachrichten und Umgänge damit hinterlegen kann. Ja, ein Fehler muss ja nicht unbedingt bedeuten, dass die ganze Anwendung crasht oder dass alles zusammenbricht, dass man dem Nutzer eine endgültige Fehlermeldung anzeigt, sondern es kann ja wirklich auch sein, dass die graceful gehandelt werden und dass es weitergeht. Und dein Beispiel zu dem Login-Screen, den man dann nochmal bekommt, weil man nicht mehr autorisiert ist, weil man nicht mehr angemeldet ist, das ist natürlich ein super Beispiel dann auch dafür. Und das eine ist natürlich, dass die Kunden das bekommen, die die Anwendung benutzen.

  5. 14:08

    Also ich sage mal jetzt wirklich eine Person, die sich da durchklickt viel öfter. Und wichtiger ist wahrscheinlich sogar der Fall, dass wir den Programmierern selbst einerseits helfen, aber auch Leuten, die zum Beispiel eine API konsumieren. Und gerade bei einer API, wenn ich da einen Wert schicke, der zum Beispiel einen Range Error erzeugt, also eine Zahl, die zu groß ist, oder einen Type Error, also dass ich vielleicht einen String erwarte und aber eine ganze Zahl geschickt habe oder so. Das sind natürlich die Sachen, wo ich wirklich durch einen Error sehr, sehr explizit direkt sehen kann, was das Problem ist und wo ich sonst vielleicht lange Recherche machen müsste

  6. 14:43

    oder nachfragen müsste, was denn genau hier das Problem ist. Die Hauptidee bei so einem Error ist ja, dass man alles dafür tut, dass der nicht wieder auftritt, weil er den normalen Programmablauf behindert. Und das kann zum einen für den Nutzer gelten, also anderes klassisches Problem, Beispiel aus der Nutzersicht ist so ein Validierungsfehler, was du gerade auch bei der API gesagt hast. Man trägt in einem Feld irgendwas ein und das erfüllt irgendwelche Validierungskriterien nicht. Dann ist das auch eine Art von Error, das direkt an der Stelle angezeigt wird und dem Nutzer sagt, hey, schau mal hier, dein Geburtstag kann nicht 1600 irgendwas sein, da stimmt irgendwas nicht.

Fehler mitbekommen 15:19–17:22

  1. 15:19

    Aber genauso wie das für den Konsumenten möglichst informativ sein soll, damit er was gegen diesen Error tun kann,

  2. 15:27

    muss es natürlich auch für uns als Entwickler sein. Weil häufig genug sind Errors auch irgendwelche technischen Dinge, für die der Nutzer jetzt nichts tun kann oder der API-Konsument, was du gerade gesagt hast. Und dann ist es aber trotzdem für uns als Entwickler wichtig, A, wie ist dieser Error überhaupt zustande gekommen? Und B, was können wir jetzt dafür tun, dass der nicht wieder vorkommt? Die Errors haben ja normalerweise den Stacktrace, den sie auch mitbringen, sodass jemand, der den Error tatsächlich zu Gesicht bekommt, ganz gut rausfinden kann, wo ist der Fehler entstanden und was könnte auch die Ursache sein.

  3. 16:00

    Das Problem ist aber häufiger, dass jemand den Fehler bekommt, der jetzt nicht gerade der Entwickler selbst ist. Und wie der Fehler dann bei uns ankommt, das ist ein großes Thema. Und wir glauben, dass wir da eine ganz gute Lösung für haben, indem wir die Fehler in den größeren Projekten bei uns extern loggen und auch auswerten. Ja, es gibt eigentlich fast keine andere Möglichkeit, sobald das Projekt eine gewisse Größe erreicht hat, dass man die Fehler irgendwo hinschickt. Im Backend, wenn man auf einem Server unterwegs ist und da irgendwelche Fehler entstehen, ist es nochmal ein bisschen einfacher,

  4. 16:33

    weil man sie direkt auf dem Server irgendwie loggen kann im allerbasigsten Fall. Aber wenn, so wie wir im Frontend unterwegs sind, dann wird so ein Fehler vielleicht in der Konsole geworfen und dann kriegt ihn bestenfalls noch der Nutzer mit, der da gerade vor dem Display sitzt. Aber wir als Entwickler nicht. Und deswegen ist es, glaube ich, da unumgänglich, dass man eben diese Errors alle einsammelt und an irgendeine zentrale Stelle loggt. Da benutzen wir jetzt zum Beispiel Sentry, um mal was gesagt zu haben. Ich glaube, das ist sogar ein Premium-Tier, was wir da haben. Also das soll jetzt keine Werbung sein,

  5. 17:08

    nur als Inspiration, dass es eben massig Dienste da draußen gibt, die darauf spezialisiert sind und auch SDKs für die verschiedenen Frameworks anbieten, um da strukturiert die Fehler hinzuschicken, um sie danach auswerten zu können. Und das ist noch ein anderer Punkt, warum das so entscheidend ist, die Errors selber zu werfen, weil man dann ganz genau entscheiden kann, an welcher Stelle werfe ich die. Du hast eben Stacktrace gesagt und das ist ja letzten Endes die Stelle im Code, an der der Fehler entsteht. Und aber auch, welche zusätzlichen Informationen sind denn wichtig, damit ich nachher nur anhand dieser Fehlermeldung

Fehler sinnvoll gestalten 17:22–18:07

  1. 17:44

    in zum Beispiel Sentry nachvollziehen kann, wie es da hingekommen ist. Weil wenn da nur steht, hier war ein, weiß ich nicht, ein Range-Fehler oder sowas, aber keine weiteren Informationen, dann kann ich als Entwickler auch nicht hingehen und da vielleicht zusätzliche Checks einbauen oder sonst irgendwas machen. Also ich muss möglichst präzise wissen, welche Umstände waren gegeben, dass dieser Fehler entstanden ist. Ja, das Schöne bei Tools wie Sentry ist ja, dass viele Sachen auch schon erfasst werden, ohne dass wir explizit dafür was machen müssen. Gerade bei uns im Web-Frontend ist es natürlich super interessant,

Datenschutz beim Error-Handling 18:07–19:12

  1. 18:18

    zum Beispiel, was für ein Rechner benutzt derjenige, was für ein Betriebssystem, was für ein Browser. Und daraus lässt sich manchmal dann schon das eine oder andere ableiten, wenn ein Fehler zum Beispiel immer nur in Firefox kommt. Und das ist mega hilfreich. Da sind wir natürlich so ein bisschen auf des Messers Schneide, weil einerseits wir so viele Informationen haben wollen, wie eben möglich, aber man andererseits natürlich auch den Datenschutz an der Stelle beachten muss, eben weil so viele Sachen automatisiert gelockt werden können. Und vielleicht auch, wenn man ganz viel Pech hat, bei so einer Login-Maske, wenn da ein Fehler entsteht,

  2. 18:53

    irgendein Passwort mitgelockt wird. Das darf natürlich auf keinen Fall passieren. Also da muss man auch sensibilisiert für sein, nicht vielleicht einfach blind alles zu loggen, was da ist, sondern so ein bisschen zu schauen, wie muss ich das vielleicht anonymisieren, welche Sachen muss ich rausfiltern, damit eben der Datenschutz auch gesichert ist. Definitiv, genau. Wir haben jetzt gerade schon die Nutzersicht ein bisschen angeschnitten, aber ich glaube, für die Entwicklersicht ist es auch am entscheidendsten. Da komme ich gleich nochmal zurück, deswegen mache ich diesen Boden, diesen Bogen. Aus Entwicklersicht ist es am wichtigsten,

Error-Handling Konzepte 19:12–23:12

  1. 19:25

    wo ist der Fehler passiert und welche Informationen führen dahin. Und dann werfe ich einen Error und fange den irgendwo ab. Also eigenes Error-Handling implementieren und das nicht irgendwie dem Browser überlassen. Und für den Nutzer ist dann entscheidend, erstmal, das reagiert wird auf die Eingabe und der Nutzer weiß, was Phase ist. Das war jetzt ein Satz, der irgendwie nirgendwo hingeführt hat. Also was ich sagen möchte ist, es macht dann Sinn, wenn es um das konkrete Error-Handling geht, innerhalb der Anwendung so Bubbles zu schaffen, also vielleicht Anwendungsbereiche, die irgendwie zusammengehören

  2. 19:59

    und da ein einheitliches Error-Handling zu schaffen für Bereiche, die da drin passieren. Weil es führt jetzt, glaube ich, nicht so viel hin, wenn man an jeder Stelle, wo ein Error passieren kann, dass man da auch ein sehr elaboriertes Error-Handling macht, weil das wird dann sehr schnell sehr aufwendig, sondern dass man sich so Abschnitte innerhalb der Anwendung definiert, wo man sagt, für diesen Bereich, alles, was hier drin an Errors geschieht, das fange ich ab und handelt das zentral ab und kann dann auch dem Nutzer für diesen Bereich eine sinnvolle Fehlermeldung und ein individuell designtes UI anbieten,

  3. 20:37

    statt im Frontend zum Beispiel, dass die ganze Anwendung abstürzt oder so. Ja, wie groß man diese Bereiche dann schneidet, das ist natürlich dann sehr, sehr individuell von Code zu Code. Was ich immer interessant finde, ist die Fehlerbehandlung auch so ein bisschen von der Business-Logik zu trennen, einfach aus dem Hintergrund, dass wir nicht den ganzen Code so verwüsten, nur dadurch, dass wir überall so Try-Catch-Blöcke drin haben, also irgendwie einen Error-Handling in irgendeiner Form. Auf der anderen Seite finde ich, das geht so ein bisschen in die Richtung, was du gesagt hast, kommen wir ja früher von so einem Modus,

  4. 21:08

    wo man in Java, meine ich, war das immer so, alles einfach in einen großen Try-Catch-Block gepackt hat und wenn irgendwo ein Fehler entsteht, dann machen wir damit irgendwas. Das ist wahrscheinlich dann zu allgemein. Also ich will nur sagen, wie man das schneidet im einzelnen Projekt, das ist dann, glaube ich, schon eher individuell, aber ich gehe genau deiner Meinung mit. In vielen Bereichen macht es Sinn, etwas größer drauf zu gucken, als dann wirklich jeden einzelnen Fehler irgendwie im Detail abzufangen. Genau, es ist dann immer so ein bisschen entscheidend, welcher Aspekt der Anwendung ist da jetzt schiefgelaufen.

  5. 21:40

    Wenn es zum Beispiel so eine Backend-Request ist, wo ganz viele unterschiedliche Requests hingeschickt werden, wie das bei uns bei so einem Laravel-API-Backend klassisch ist, da kann man dann ruhig einen einzelnen Request komplett abschießen, natürlich da mit entsprechendem Status-Code und Meldung und so weiter. Da ist es dann nicht so dramatisch, während im Frontend, wenn da irgendwo oben rechts ein Button nicht richtig angezeigt werden kann, weil einem Pfad fehlt zum Beispiel, ist es nicht so sonderlich gut, wenn die komplette Anwendung weiß wird, was ja bei so Single-Page-React-Applications

  6. 22:10

    dann passiert. Da macht es dann schon Sinn, React-Boundaries zu verwenden, um dann mal ein paar Fachwörter einzustreuen, um Teile der Anwendung zu unterteilen und so error-sicher zu machen. Ja, da gibt es ja, wenn man da jetzt ins Detail geht, auch noch irre Unterschiede. Wenn man jetzt mal im JavaScript-Bereich bleibt, Node.js zum Beispiel fällt ja bei den Errors direkt und führt zum Beispiel auch andere asynchrone Requests oder andere asynchrone Prozesse nicht mehr aus, während dann JavaScript das im Browser ausgeführt wird, ja zum Beispiel ein Set-Timeout, der noch läuft, zum Beispiel noch ausfüllen würde.

  7. 22:44

    Und da muss man sich dann schon auch ein bisschen genau auskennen, wo man was abschießt und wie man welchen Fehler dann handelt. Also da kann man schon sehr tief einsteigen, wenn man das möchte. Genau, und das ist dann auch sehr Tech-Stack-spezifisch. Deswegen weiß ich gar nicht, ob das einen großen Mehrwert hat, wenn wir jetzt noch auf so Besonderheiten eingehen, weil wir sind jetzt natürlich viel in JavaScript unterwegs, deswegen beschäftigen wir uns damit viel, aber auch zum Beispiel viel im PHP-Backend. Ich glaube, entscheidend ist, und das soll auch der Mehrwert der heutigen Folge sein, so ein Error oder so eine Exception,

Fazit 23:12–25:48

  1. 23:18

    wie auch immer das dann heißt, bietet sehr, sehr viele Möglichkeiten damit umzugehen. Und ich würde mal behaupten, sehr viele Tech-Stacks haben sehr elaborierte Datenflüsse für Error-Handling. Also Try-Catch-Blöck hast du schon gesagt, aber generell Stack-Trace und diese ganze Benennung. Das gibt so viele Möglichkeiten, den Code deutlich zu formatieren, beziehungsweise deutlich oder einen ausdrucksstarken Code zu schreiben, will ich sagen, dass das eine vertane Chance ist, wenn man diesen kompletten Aspekt des Tech-Stacks außer Acht lässt. Also deswegen keine Angst vor Errors oder vor Exceptions,

  2. 23:56

    das große Motto dieser Folge, und lernen, damit umzugehen. Das ist keine Gefahr, das ist nichts Böses, das ist nichts Schlimmes. Es kann potenziell gefährlich sein, man muss lernen, damit umzugehen, und man muss vor allem lernen, man muss mal so ein Error in Sentry oder sonst wo gesehen haben, um zu wissen, welche Informationen ich denn mitschicken muss, damit das nachher möglichst aussagekräftig ist. Und das ist, glaube ich, das große Take-away. Einfach mal damit beschäftigen und das nicht als Gefahr ansehen. Und die Tech-Stack-spezifischen Implementierungen, die unterscheiden sich dann so ein bisschen,

  3. 24:32

    aber das kann man dann im Detail sich anschauen. Das war schon ein richtig gutes Fazit. Was du gezogen hast, ich fasse das in den drei Punkten noch kurz zusammen. Wenn etwas schiefläuft, wollen wir einen Error werfen und dürfen keine Angst davor haben, einen Error zu werfen. Ich schmeiße da nochmal Fail Early, Fail Loudly rein, so als Prinzip, dass wir möglichst früh einen Fehler visualisieren wollen. Dann wollen wir spezielle Error-Typen bestenfalls verwenden, die wirklich konkret auf ein bestimmtes Problem hinweisen, bestenfalls mit einer Custom-Message, mit einer individuellen Nachricht, wo jemand, der den Fehler bekommt,

  4. 25:06

    auch erst mit anfangen kann. Und als unsere Empfehlung aus unserer Praxis, dass man wirklich Errors auch extern loggen und auswerten sollte, weil man dann von Fehlern überhaupt erst mitbekommt, die sonst vielleicht an einem vorbeigegangen wären und man noch ganz andere Möglichkeiten hat, mit der Menge an Fehlern dann auch umzugehen. Ich kann ja sagen, ich als Entwickler mache keine Fehler, ich mache Errors. Schön. Das ist ein guter Abschluss der Folge und Kay, ich freue mich auf die nächste und danke dir erstmal. Danke dir auch und schönen Tag noch. Bis dahin.

03 — Weiterhören

Nebenan im Webcafé

Alle zwei Wochen montags eine neue Folge über Webentwicklung, Codequalität und die Art, wie wir zusammenarbeiten.

Alle 52 Folgen
04 — Feedback

Fragen an Felix und Kay?

Themenwunsch, Widerspruch oder eine Frage aus Deinem Projektalltag — schreib uns. Was uns erreicht, landet regelmäßig in einer der nächsten Folgen.

podcast [at] geenen-it-systeme.de