Ankündigung

Einklappen
Keine Ankündigung bisher.

Fehlermeldungen und Fehlercodes, Konzept?

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Fehlermeldungen und Fehlercodes, Konzept?

    Sers

    Ich bastel mir gerade eine Klasse welche über set_error_handler und set_exception_handler eine standardmäßige Fehlerbehandlung und Debugfunktionen liefern soll (z.B. kontrollierte Ausgabe von Notices und Warnings anstatt am Seitenanfang etc.) sodas man in einem produktiven System das error_reporting anschalten kann ohne gleich alles zu zerstören.

    Die Klasse steht, doch bevor ich nun weitermache bin ich am überlegen wie ich Fehlertypen, Fehlermeldungen und Fehlercodes am gescheitesten organisiere.

    Dazu hab ich im Netz leider nicht viel finden können deswegen frage ich hier.

    Zunächst gilt es ja Fehler in Typen zu klassifizieren.

    Notice - Fehler die den Programmablauf nicht beeinträchtigen aber ggf. zu unerwünschten Resultaten führne können
    Warning - Fehler welche eine Funktion/Methode zum Abbruch zwingen, Programm/Script kann weiter ausgeführt werden
    Exception - Fehler welche das Programm/Script zum Abbruch zwingen wenn sie nicht behandelt werden können
    Error - Fehler die nicht behandelbar sind und das Programm/Script stoppen

    Kann man das als Klassifizierung so stehen lassen?

    Weiter geht es mit der Organisation von Fehlercodes und -meldungen.

    Die Fehlermeldungen direkt in den Code zu schreiben halte ich generell für eine schlechte Idee da sie dann schlecht wartbar/korrigierbar sind. Also Dinge a la:

    PHP-Code:
    trigger_error('shit happens!'); 
    Ich habe bloß keine Idee wie ich das zentral gut verwalten kann, sodas man im Code dennoch erkennt um welchen Fehler es sich handelt.

    Ich suche also etwas a la:

    PHP-Code:
    define('SHIT_ERROR''shit happens!');
    trigger_error(SHIT_ERROR); 
    Die Liste an Konstanten wäre bloß auf die Dauer ziemlich lang. Das gleiche gilt für Fehlercodes. Fakt ist aber das die Meldungen ja eh irgendwo niedergeschrieben werden müssen. Nur wie und wo?

    Davon abgesehen sollte ja auch irgendwo aufgenommen werden um welche Komponente es sich handelt (System, View, Database, Registry, Modul etc.) die den Fehler ausgelöst hat.

    Wie organisiert ihr sowas? Nach welchen Konzepten geht ihr da vor oder habt ggf. Lektüre für mich die gängige Konzepte erleutert?

    Wie gesagt, meine Googlesuche war nicht wirklich aufschlussreich deswegen frage ich euch (ich weise darauf hin weil ich die Forumsrichtlinien zu Inseraten, Ideen, Meinungsumfragen kenne ).
    "Alles im Universum funktioniert, wenn du nur weißt wie du es anwenden musst".

  • #2
    Hallo,

    sodas man in einem produktiven System das error_reporting anschalten kann ohne gleich alles zu zerstören
    Das error_reporting() ist da eigentlich nicht ausschlaggebend, vielmehr die Option "log_errors" und "display_errors". Da musst du nicht selbst einen Wrapper für schreiben!

    trigger_error() würde ich grundsätzlich nicht mehr benutzen, stattdessen lieber eine Exception werfen, die du dann an entsprechender Stelle fangen kannst. Ich biege bspw. mit set_error_handler() alle Fehler auf eine ErrorException um, so dass ich wirklich alles fangen kann, was zu fangen ist. Konstanten als Fehlermeldungen zu verwenden finde ich auch keine gute Idee, hat sich zumindest nicht als praktikabel erwiesen. Einfach englischen Kurztext tippen und vor der Ausgabe (falls du die Exception nicht fängst) einfach übersetzen (Array-Mapping oder wie dein Übersetzungsmodul funktioniert, falls du eines hast) oder im Produktivsystem sowieso durch eine deutsche Standardfloskel ersetzen. Exceptions sollten sowieso nicht bis zum Benutzer stossen, daher kann es - meiner Meinung nach - da auch ruhig technisch und englisch zur Sache gehen. Als Identifier für die Art der Exception benutze ich schändlicherweise die HTTP-Codes: 403, wenn die ACL deny meldet, 404 wenn ein Model nichts findet oder 500 bei anderen Sachen.

    Lies dich doch mal ins Exception-Handling ein.
    "[URL="http://www.youtube.com/watch?v=yMAa_t9k2VA&feature=youtu.be&t=25s"]Mein Name ist Lohse, ich kaufe hier ein.[/URL]"

    Kommentar


    • #3
      Da die Fehlermeldungen den Benutzer nichts angehen handhabe ich das so wie Chriz - ich schreib das rein, was _mich_ an der Stelle interessiert.
      Über das ErrorReporting/Exceptions sammle ich mir dann noch notwendige Infos, schreib die in meine Log und zeig dem Benutzer "Es ist ein Fehler aufgetreten".
      Schließlich muss man ja nicht alles verkomplizieren - und sauberes Englisch sollte jeder verstehen, der sich mit ErrorLogs beschäftigen und am Script werkeln muss.
      VokeIT GmbH & Co. KG - VokeIT-oss @ github

      Kommentar


      • #4
        Mit Exceptionhandling kenne ich mich aus, auch aus anderen Programmiersprachen.

        Die Wrapperklasse ist - teilweiße - notwendig wenn ich mal überlege wie es bei uns in der Firma zugeht. Da werden dann Bedingungen gebastelt welche das error_reporting und display_errors nur für unsere IP hochschrauben weil wenn du jemanden fragst "sag mir mal wo ich auf server xxx die php error logs finde" gibts nur ein "hääää?".

        Bei uns Livesysteme zu debuggen ist ein Graus. Daher die Wrapperklasse denn falls mein Stückchen Software doch mal meinen Rechner verlässt soll wenigstens die Möglichkeit vorhanden sein.

        Was die Meldungen und Codes an sich angeht: Ich liebäugel gerade schon wieder mit XML als Ablageformat. Ist mit simpleXML schnell eingebaut und in viele Richtungen erweiterbar.

        Nur das Konzept ist mir noch unklar über die Anordnung des ganzen.

        VN0001 - "View Notice Nr. 1"
        VW0001 - "View Warning Nr. 1"

        Oder sollten Fehlercodes prinzipiell nur Zahlen beinhalten? Bei Exceptions ist es ja relativ einfach eine Komponente zuzuordnen da man i.d.R. für jeden Exceptiontyp eine eigene Klasse von Exception erben lässt.
        "Alles im Universum funktioniert, wenn du nur weißt wie du es anwenden musst".

        Kommentar


        • #5
          Dann testet besser. Ich glaube ich verstehe aber nicht so ganz was du vor hast, was willst du mit XML anfangen?
          "[URL="http://www.youtube.com/watch?v=yMAa_t9k2VA&feature=youtu.be&t=25s"]Mein Name ist Lohse, ich kaufe hier ein.[/URL]"

          Kommentar


          • #6
            Zitat von Chriz Beitrag anzeigen
            Dann testet besser. Ich glaube ich verstehe aber nicht so ganz was du vor hast, was willst du mit XML anfangen?
            Mir geht es gerade hauptsählich um folgende Dinge:

            - Strukturierung der Fehlercodes+Fehlermeldungen (Codes als laufende Nummer oder "anders"?)
            - Flexible Speicherung der Fehlercodes+Meldungen (XML ist da am einfachsten zu Erweitern)
            - Zugriff über einen Schlüssel welcher den Inhalt der Meldung erkennbar widerspiegelt
            - Einbindung in das System (Ggf. ein Singleton zum Abruf? oder nur eine statische Methode im Wrapper?)

            Besser testen lässt sich nicht durchsetzen, schon versucht. Davon ab das ich davon ausgehe das das es bei vielen Entwicklern so ausschaut.
            "Alles im Universum funktioniert, wenn du nur weißt wie du es anwenden musst".

            Kommentar


            • #7
              Hi,

              wenn du auf Fehlercode stehst: Als eindeutiger Bezeichner eignet sich Dateipfad und Zeilennummer. Das lässt sich auch prima automatisieren

              Fehlermeldungen in meinen Projekten werden grundsätzlich per Mail verschickt und in einem Logfile gespeichert. Dabei enthält jede Meldung:
              - einen Titel (z.B. Exception-Message). Dieser muss (für dich) klar und verständlich ausdrücken, was schief gelaufen ist. Also nicht "Scheisse, geht nicht", sondern "Benutzer nicht eingeloggt: Mehr als ein Datensatz passte"
              - ein komplettes Backtrace (Skalar-und Array-Argumente mit Inhalt, bei Objekten nur Objekttyp)
              - eine (leicht gefilterte) Liste der globalen Variablen
              - oder, wenn Zend Framework zum Einsatz kommt, GET, POST, COOKIE, SESSION und SERVER
              - Zusätzlich noch ein paar wichtige Variablen deiner Applikation.

              Die Signatur meiner Funktion:
              ReportAppError(string $title, Exception $ex, ...)
              Sämtliche Argumente hinter $ex werden per print_r($x, true) an die Meldung angehängt.


              Hoffe das hilft - ist zumindest die Essenz von > 10 Jahren PHP Entwicklung.


              Grüße
              Thomas

              Kommentar


              • #8
                Nun, folgendes werde ich nun wohl umsetzen:

                Code:
                <?xml version="1.0" encoding="UTF-8"?>
                <!DOCTYPE errorSpec PUBLIC "-//Thryme CMS//Error Specification//EN" "../../dtd/errorSpec.dtd">
                <errorSpec>
                    <notices>
                        <notice access="SY_NTC_APP_NAME" class="System" method="initialize" code="SY-000001" message="Application name not found, loading default Application '%S'" />
                    </notices>
                
                    <warnings>
                        <warning access="SY_WNG_QRY_STRING" class="System" method="initialize" code="SY-000010" message="Querystring was empty." />
                    </warnings>
                
                    <errors>
                        <error access="SY_ERR_EMPTY_EXT_LIST" class="System" method="initialize" code="SY-000020" message="No system class extensions could be found." />
                        <error access="SY_ERR_INV_EXTENSION"  class="System" method="loadExtension" code="SY-000021" message="Invalid extension class name '%S'." />
                    </errors>
                </errorSpec>
                Beispiel XML zur Ablage der Meldungen vom System. Die Trennung in verschiedene Dateien je nach Komponente ermöglicht es mir die Listen kurz zu halten und problemlos dynamisch (bei der installation eines Moduls beispielsweiße) weitere Meldungen hinzuzufügen.

                Geladen wird das ganze wie folgt:
                PHP-Code:
                $e ErrorManager::getInstance();
                $e->setErrorSpecificationDirectory('../../debug/err_spec/'); // wird nur einmal in der bootstrap Datei ausgeführt.
                $e->addErrorSpecification('system.xml'); 
                Geworfen wird das ganze durch eine Funktion ähnlich trigger_error welche ledeglich den in access definierten Wert benötigt und die korrekte Anzahl an Parametern für die Meldung und dies an den ErrorManager durchschleift.

                Für Exceptions lege ich eine Klasse an welche mit den gleichen Parametern wie meine Funktion auskommt damit der Aufruf von "throw new" möglich bleibt und diese noich gefangen werden können.

                Kann man damit Leben?
                "Alles im Universum funktioniert, wenn du nur weißt wie du es anwenden musst".

                Kommentar


                • #9
                  Ich halte sowas für unpraktikabel und praxisfern. Fehler sollten beseitigt werden, nicht kunstvoll geloggt. Zudem sind nur ein Teil von in PHP möglichen Fehlerklassen abzufangen (andere nur mit sehr viel FooBar). Ich würde zu Exceptions und einfachen Logfiles raten.
                  [COLOR="#F5F5FF"]--[/COLOR]
                  [COLOR="Gray"][SIZE="6"][FONT="Georgia"][B]^^ O.O[/B][/FONT] [/SIZE]
                  „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                  [URL="http://www.php.de/javascript-ajax-und-mehr/107400-draggable-sorttable-setattribute.html#post788799"][B]Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“[/B][/URL][/COLOR]
                  [COLOR="#F5F5FF"]
                  --[/COLOR]

                  Kommentar


                  • #10
                    Zitat von nikosch Beitrag anzeigen
                    Ich halte sowas für unpraktikabel und praxisfern. Fehler sollten beseitigt werden, nicht kunstvoll geloggt..
                    Es geht ja nicht um kunstvoll sondern um eine möglichst aussagekräftige Fehlerbehandlung die den Zweck erfüllt den Entwickler mit mehr Informationen als nur einer Zeilennummer zu versorgen (das macht u.A. meine Wrapperklasse welche die Fehler sammelt und loggt) und gleichzeitig dafür zu sorgen das die Anwendung nicht wegen jedem Furz (Es wurde ein String anstatt eines Integers übergeben - warum auch immer) abbricht und der Besucher nur noch weiss sieht mit "Es ist ein Fehler aufgetreten".

                    An unserer Firma sehe ich was passiert wnen eine vernünftige Fehlerbehandlung fehlt und sich auf display_errors verlassen wird. Dem will ich entgegen wirken.
                    "Alles im Universum funktioniert, wenn du nur weißt wie du es anwenden musst".

                    Kommentar


                    • #11
                      An unserer Firma sehe ich was passiert wnen eine vernünftige Fehlerbehandlung fehlt und sich auf display_errors verlassen wird. Dem will ich entgegen wirken.
                      dafür zu sorgen das die Anwendung nicht wegen jedem Furz (Es wurde ein String anstatt eines Integers übergeben - warum auch immer) abbricht
                      Sorry, das kann ich nicht nachvollziehen. Typverletzungen ergeben eine Notice und noch lange keinen Programmabbruch. Fehler bei Gefahr von Folgefehlern ergeben Warnings. Auch hier läuft alles weiter. Fatal errors werden abgebrochen, weil die Fortführung der Applikation damit nicht möglich ist - eine fehlende Ressource kann man eben auch nicht auslesen.
                      PHP hat eine sehr sinnvolle Art, Fehler zu behandeln. Das Logfile sagt einem alles, was man braucht (es sei denn, man benötigt den kompletten Aufrufstack) und display_errors hält wirkungsvoll Fehlermeldungen von Besuchern fern.
                      [COLOR="#F5F5FF"]--[/COLOR]
                      [COLOR="Gray"][SIZE="6"][FONT="Georgia"][B]^^ O.O[/B][/FONT] [/SIZE]
                      „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                      [URL="http://www.php.de/javascript-ajax-und-mehr/107400-draggable-sorttable-setattribute.html#post788799"][B]Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“[/B][/URL][/COLOR]
                      [COLOR="#F5F5FF"]
                      --[/COLOR]

                      Kommentar


                      • #12
                        Es ist sehr problematisch, wenn ein Loggingsystem selbst ein komplexes System ist.
                        Du weißt nicht welche Fehler auftreten, du kannst unmöglich alle vorhersehen, welche Infos dir vorliegen, etc. Außerdem können kurz- und langfristig riesige Datenmengen entstehen, die man eigentlich nicht mit XML aufblähen will. Der Overhead von XML ist bei dir sicherlich > 50%, vermutlich sehr viel mehr. Diese Datenmengen wollen auch analysiert werden oder zumindest übersichtlich aufbereitet werden. Parse doch mal ein 800 MB XML-Logfile. Ich glaube du hast gute Intentionen, aber einfach zuwenig Erfahrung.

                        Im Übrigen ist es auch völlig unnötig, denn eine Exception hat eine Message, einen Code, einen Backtrace und du kannst Exceptions auch stacken, also herausfinden welche Exception möglicherweise welche Exception ausgelöst hat. Natürlich kannst du der Exception auch zusätzliche Methoden spendieren. Recht flexibel also. Zugegeben wirds dann auch mit dem Loggen und der Datenmenge schwierig, aber die Information ist da und einfach "stringifizierbar". Wenn man alle Infos haben will, muss man eben mit großen Datenmengen leben.

                        gleichzeitig dafür zu sorgen das die Anwendung nicht wegen jedem Furz (Es wurde ein String anstatt eines Integers übergeben - warum auch immer) abbricht und der Besucher nur noch weiss sieht mit "Es ist ein Fehler aufgetreten".
                        Tut sie auch nicht. Aber wenn ein Fehler aufgetreten ist und die Anwendung nicht weiterlaufen kann, geht es den Benutzer nichts an ob das Datenbankpasswort falsch ist oder der Speicher nicht ausreicht. Fehler ist Fehler, relevant ist lediglich ob es weitergehen kann oder nicht. Und das kannst du am Besten mit Exceptions entscheiden.

                        Abgesehen davon hast du den Error-Reporting Mechanismus nicht so wirklich verstanden oder? Du kannst ihn runterschrauben, ein-/ausblenden und loggen, alles separat. Wenn dein Error-Reporting auf 0 ist, wird auch - bei entsprechender Prüfung - niemals eine ErrorException geworfen. Selbst auf @ kannst du angemessen reagieren (nämlich z.B. garnicht). Insofern ist dein Argument hinfällig.

                        Ich kann dich nur abschließend vor einem komplexen Logging warnen. Was du draus machst ist dein Senf
                        "[URL="http://www.youtube.com/watch?v=yMAa_t9k2VA&feature=youtu.be&t=25s"]Mein Name ist Lohse, ich kaufe hier ein.[/URL]"

                        Kommentar


                        • #13
                          Zitat von nikosch Beitrag anzeigen
                          Sorry, das kann ich nicht nachvollziehen. Typverletzungen ergeben eine Notice und noch lange keinen Programmabbruch. Fehler bei Gefahr von Folgefehlern ergeben Warnings. Auch hier läuft alles weiter. Fatal errors werden abgebrochen, weil die Fortführung der Applikation damit nicht möglich ist - eine fehlende Ressource kann man eben auch nicht auslesen.
                          PHP hat eine sehr sinnvolle Art, Fehler zu behandeln. Das Logfile sagt einem alles, was man braucht (es sei denn, man benötigt den kompletten Aufrufstack) und display_errors hält wirkungsvoll Fehlermeldungen von Besuchern fern.
                          Zitat von Chriz Beitrag anzeigen
                          Es ist sehr problematisch, wenn ein Loggingsystem selbst ein komplexes System ist.
                          Du weißt nicht welche Fehler auftreten, du kannst unmöglich alle vorhersehen, welche Infos dir vorliegen, etc. Außerdem können kurz- und langfristig riesige Datenmengen entstehen, die man eigentlich nicht mit XML aufblähen will. Der Overhead von XML ist bei dir sicherlich > 50%, vermutlich sehr viel mehr. Diese Datenmengen wollen auch analysiert werden oder zumindest übersichtlich aufbereitet werden. Parse doch mal ein 800 MB XML-Logfile. Ich glaube du hast gute Intentionen, aber einfach zuwenig Erfahrung.

                          Im Übrigen ist es auch völlig unnötig, denn eine Exception hat eine Message, einen Code, einen Backtrace und du kannst Exceptions auch stacken, also herausfinden welche Exception möglicherweise welche Exception ausgelöst hat. Natürlich kannst du der Exception auch zusätzliche Methoden spendieren. Recht flexibel also. Zugegeben wirds dann auch mit dem Loggen und der Datenmenge schwierig, aber die Information ist da und einfach "stringifizierbar". Wenn man alle Infos haben will, muss man eben mit großen Datenmengen leben.


                          Tut sie auch nicht. Aber wenn ein Fehler aufgetreten ist und die Anwendung nicht weiterlaufen kann, geht es den Benutzer nichts an ob das Datenbankpasswort falsch ist oder der Speicher nicht ausreicht. Fehler ist Fehler, relevant ist lediglich ob es weitergehen kann oder nicht. Und das kannst du am Besten mit Exceptions entscheiden.

                          Abgesehen davon hast du den Error-Reporting Mechanismus nicht so wirklich verstanden oder? Du kannst ihn runterschrauben, ein-/ausblenden und loggen, alles separat. Wenn dein Error-Reporting auf 0 ist, wird auch - bei entsprechender Prüfung - niemals eine ErrorException geworfen. Selbst auf @ kannst du angemessen reagieren (nämlich z.B. garnicht). Insofern ist dein Argument hinfällig.

                          Ich kann dich nur abschließend vor einem komplexen Logging warnen. Was du draus machst ist dein Senf
                          Eben weil ich das Verfahren von PHP recht sinnvoll finde versuche ich dies auf meine eigenen Klassen/Methoden/Funktionen anzuwenden und nicht für alles eine Exception zu werfen (wie es wiederholt vorgeschlagen wurde).

                          Die gezeigte XML Struktur ist auch nicht die Ausgabe des Loggings sondern die Eingabe der Meldungen in das System. Die Ausgabe sieht anders aus.

                          Und eben auch weil ich nicht alle Fehler vorhersehen kann, also nicht dne ganzen Code mit try ... catch aufblähen möchte nutze ich die Unterteilung in Notices, Warnings und Errors/Exceptions um an gegebener Stelle eine Meldung in angemessener Höhe zu liefern.

                          Und wirklich komplex ist das System nicht. Besteht bisher aus einer Klasse und einem Ordner zur Ablage der Meldungen und der Logs.
                          "Alles im Universum funktioniert, wenn du nur weißt wie du es anwenden musst".

                          Kommentar


                          • #14
                            Also ich habe für unser System in der Firma mal eine Exception-Handling Klasse geschrieben, die alle geworfenen Exceptions mit Tracestring in die DB schreibt und wenn die mal nicht verfügbar ist, dann eine Email verschickt. Und wenn auch das nicht geht, wird versucht in eine log-Datei zu schreiben. Und im Zend_Framework werden viele Exceptions geworfen
                            Analog sollte es auch mit set_error_handler gehen.
                            Sollte das alles nicht funktionieren, na dann shit happens. Also mit der DB sind wir bischer ganz gut gefahren. Mit einem kleinen Webinterface, in dem man die Fehler abarbeiten kann, ist die Sache auch schnell erledigt.
                            "My software never has bugs, it just develops random features."
                            "Real programmers don't comment. If it was hard to write, it should be hard to understand!"

                            Kommentar


                            • #15
                              @Paul.Schramenko: Quasi ein Auto-Mantis , Das wäre eine Idee die ich bei uns auch mal vortragen könnte

                              Also ich würde dir, genauso wie nikosch, stark empfhelen mit Exceptions / ErrorExceptions zu arbeiten. Da bekommt man eine Detalierte ausgabe mit Trace etc, besser debuggen kann man dann nur noch mit externen Tools (xDebug, etc.).

                              Im produktiven Einsatz dürften aber keine Fehler mehr auftauchen.

                              Ich catche Errors mit ErrorException und gebe sie dann an meinen Exceptionhandler weiter. Dann habe ich immer einen zentralen Punkt zum handeln von Errors und Exceptions. Bei Fatal errors greift ErrorException (glaube ich) nicht.

                              Bei großen Applikationen empfhielt es sich für einzelne Komponenten auch einzelne Exceptions zu verwenden, um auf Komponenten-Fehler möglichst optimal zu reagieren bzw. entsprechende Fehlermeldungen zu erzeugen.
                              Hybrid developer & Innovation engineer at http://grannyandsmith.com.

                              Blogging about application development and workflows at http://www.marco-bunge.com.

                              Kommentar

                              Lädt...
                              X