|
||||||||||||||||||||||||||||||||||||
Aktuell Texte Der Comic Impressum Kalender Suche PHP-Klassen Container-Wizard main.s21 |
||||||||||||||||||||||||||||||||||||
Kategorien
{{login}}
|
Fehlerketten
"Fehlerketten" sind der Grund, weshalb ich nicht gerne mit anderer Leute Bibliotheken arbeite. PHP scheint diese Pest, anders als ich, zu mögen, ebenso wie viele PHP-Programmierer. Ein Beispiel: ich wollte eine .docx-Datei öffnen, das XML-Dokument rausziehen, verändern, zurückschreiben und das ganze dann ausgeben. Ich hatte aber zum Testen eine leere .docx erstellt, was zu folgender Fehlerkette führte:
(der Zugriff auf <a> und href="" ist exemplarisch) In einer Testumgebung war der Fehler recht schnell zu finden, das hätte aber auch weitaus länger dauern können. Meiner Ansicht (und Praxis) nach sollte bereits ZipArchive::open eine Exception werfen. Man mag zwar einwenden, dass ZipArchive::open auch dazu dient, nicht existierende Archive anzulegen, aber dies ist der Grund, weshalb man an dieser Stelle die Funktionalität in ZipArchive::open und ZipArchive::create teilen sollte. Spätestens getFromName sollte eine Exception werfen. Die Fehlerbehandlung könnte gründlicher sein (Archiv leer vs. Archiv kaputt). Das Problem liegt übrigens nicht nur an PHP oder dass es keine starke Typisierung hat. Ähnlichen Bockmist kann man auch in Java verzapfen, da dort jeder Wert mit null substituiert werden kann. Einige der Collections geben stillschweigend null zurück, wenn man auf nicht existierende Werte zugreift - ein ähnlich idotisches Verhalten. Ich habe einige Grundregeln:
Dazu kommt, dass alle Klassen eine präventive Fehlervermeidung bereitstellen sollten. Im obigen Beispiel müsste ich die DOMNodeList selbst überprüfen, ob sie enthält, was ich verlangt habe. Dies geht an dieser Stelle nur, indem ich die public property DOMNodeList::length auswerte (gruselig). Dies ist dann auch das, was man in vielen Quelltexten sieht:
<?php
Ich halte es grundsätzlich so:
<?php
Dies aber auch nur, wenn man kein else { wirf Fehler} hinschreibt. Denn wenn Bar::hasValue("foo") nicht FALSE sein darf, dann kann ich auch gleich Bar::getValue() aufrufen und die Fehlermeldung von Bar::getValue durchschlagen lassen, falls foo doch fehlt. Einige meiner Kollegen halten es für verschwendete Arbeit, Prüfung nach Prüfung zu programmieren. In der Tat kann es langweilen, "Idiotencode" zu schreiben. Regelmässig am Debugger zu hängen macht mir allerdings noch viel weniger Spass. KommentierenBitte beachten: Kommentare sind nicht sofort sichtbar, sondern werden erst nach einer kurzen Prüfung freigegeben, sofern keine rechtliche Beanstandung vorliegt. |