Wo Exceptions "fangen"?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Wo Exceptions "fangen"?

    Hallo allerseits,

    ich baue derzeit mal wieder in PHP rum und quäle mich nun ein wenig mit Exceptions. Ansich sind die Dinger ja toll, man kann für unterschiedlichste Fehlertypen eigene Klassen erstellen und diese unterschiedlich weiterbehandeln. Soweit die Theorie. Wie genau arbeitet ihr aber mit Exceptions in einer OOP-Umgebung? Ich habe z.B. das Problem, dass mir nicht ganz klar ist, was "guter Stil" wäre. Wie weit soll ich die Ausnahmen durch meine Prozesslogik schleifen, bis ich sie "fange" (catch)? Beispiel:

    Quellcode

    1. if($this->__table_name == "")
    2. {
    3. throw new Framework_Exception_Database("Kann kein leeres Model erzeugen", 500);
    4. }


    Momentan behandle ich alle Exceptions auf die gleiche Weise und gebe den Fehler formatiert aus (was am Ende natürlich geändert wird, aber zum Arbeiten am bequemsten ist). Sprich:


    Quellcode

    1. // Bootstrap-Datei laden
    2. try{
    3. include APPLICATION_PATH . PATH_BACKSLASH . 'application' . PATH_BACKSLASH . 'bootstrap.php';
    4. }
    5. // Das ist so noch nicht wirklich sauber gelöst. Ich sollte mich fürs Error-Handling nochmal etwas einlesen.
    6. catch(Exception $e){
    7. echo("{$e}\n");
    8. }

    Da alle meine Exceptions von der Klasse Exception erben, kann ich am Ende einfach ausgeben, was schief gelaufen ist.

    Kurz gefragt: Wie macht man das richtig? :) Auf der Suche nach best practices wurde ich nicht fündig.
  • Hi

    ich sage ganz allgemein dazu, mir ist mir Jahren klar geworden, man muss versuchen den Fehler so gut wie möglich zu umgehen. Sprich wenn du Fehler kriegst, versuchen diesen ohne Fehlermeldung zu lösen. D.h. bei jedem try musst du ursache kennen und versuchen dies umzugehen oder nochmal zu versuchen.

    Einfach einem user eine Fehlermeldung vor die Nase schmeißen kann jeder, und MS ist der Vorreiter in so einer Programmierung :D

    und try sollst du überall anwenden, wo halt unerwarteten ergebnisse kommen könnten. d.h. benutzereingabe, datenverarbeitung aus klassen-externen quellen etc.
  • Ich orientiere mich meist an dem einfachen Prinzip "Reiche die Exception so lange wie möglich durch".

    Oft geht das bis in die grafische Oberfläche, wo dann eben entsprechend agiert wird (Fehlertext oder was auch immer).
    Du kannst ja in einem try mehrere catch anlegen. Bsp:

    Quellcode

    1. // [...]
    2. try {
    3. /*
    4. * Irgendwelche Operationsaufrufe die verschiedene Exceptions werfen können.
    5. *
    6. */
    7. }
    8. catch(VerbindungNichtMöglichException vnme) {
    9. // Behandlung
    10. }
    11. catch(Exception e) {
    12. // Allgemein, falls der andere nicht zutrifft.
    13. }
    14. // [...]
    Alles anzeigen

    Hierbei also immer vom Spezielleren zum Allgemeinen.

    Solltest du vorher agieren möchten aber es dennoch bis zum Benutzerinterface reichen wollen, kannst du dich dem "re-throwing" bedienen (einfach im catch-block noch ein throw).
  • Ich führe auch gerne viele Exception Klassen ein (natürlich weitgehend generisch).
    Fangen tue ich sie meistens nicht speziell sondern erst im äußersten catch Block mit der Standard Exception Klasse - diese benutze ich auch sonst nirgendswo sonst.
    Werfen tue ich die Standard Exception Klasse nie.

    Ich habe beim Zend ein paar Best Practices zu Exceptions gefunden:
    * framework.zend.com/wiki/displa…29-Exceptionbestpractices

    Exception best practices
    • Use specific derived exceptions in both throw and catch. See the following two items:
    • Avoid throwing the Exception base class, or other exception superclass. The more specific the exception, the better it communicates to the user what happened.
    • Avoid catching the Exception base class, or other exception superclass. If a try block might encounter more than one type of exception, write a separate catch block for each specific exception, not one catch block for an exception superclass.
    • Some classes may require you to write more than one derived exception class. Write as many exception classes as needed, to distinguish between different types of situations. For example, "invalid argument value" is different from, "you don't have a needed privilege." Create different exceptions to identify different cases.
    • Don't put important diagnostic information only in the text of the exception method. Create methods and members in derived exception classes as needed, to provide information to the catch block. Create an exception constructor method that takes appropriate arguments, and populate the members of the class with those arguments.
    • Don't silently suppress exceptions and allow execution to continue in an erroneous state. If you catch an exception, either correct the condition or throw a new exception.
    • Keep implementation-specific exceptions isolated to the appropriate layer of your application. For instance, don't propagate SQLException out of the data layer code and into business layer code.
    • Don't use exceptions as a mechanism of flow control, or to return valid return values from a function.
    • Clean up resources such as database connections or network connections. PHP does not support a finally block as some programming languages do, so either clean up in the catch blocks, or else design flow control outside the catch block to perform cleanup, and let execution continue after the catch.
    • Use documentation from other languages for other best practices regarding using exceptions. Many of the principles are applicable, regardless of the language.