My book recommendations

Exception Handling

Diesen Artikel über Exception Handling widme ich meinem Arbeitskollegen der sich dieses Thema von mir gewünscht hat.

Wollen wir auch sofort zum Thema kommen! Um es in einem Satz zu sagen: Exceptions sind Ausnahmezustände die eine Möglichkeit bieten auf verschiedene kritische Bedingungen bzw. Fehler während des Programmablaufs zu reagieren. BAM!

Geschnallt ? :-) Wenn nicht, nicht schlimm! Der Artikel fängt ja jetzt erst richtig an!

Um bei meiner lieblings Sprache zu bleiben, das Exception Handling gibt es in PHP erst seit der Version 5. Dort ist Sie standardmäßig dabei! Es muss also nix installiert, konfiguriert oder aktiviert werden! Wenn Ihr also noch mit PHP 4 arbeitet, leuteee, geht mit der Zeit :-)

Ok, das Exception Handling bietet uns also eine Möglichkeit! Wie sieht diese Möglichkeit aus? In PHP und auch in andere Sprachen gibt es das try und catch Konstrukt. Mit throw werfen wir einen Fehler und mit catch fangen wir diesen Fehler und können entsprechend auf diesen reagieren! Um das Fangen von Exceptions zu ermöglichen, muss der jeweilige Code in dem wir einen Fehler vermuten würden in einem try Block umschlossen werden. Dabei muss jeder try Block mindestens einen catch Block besitzen! Mehrere catch Blöcke sind dabei natürlich zu genaueren Filterung von Fehlern möglich.

Damit wir uns das ein bischen besser vorstellen können gibts dazu auch direkt ein Beispiel

class TestClass {
    public function sayHello($name) {
        if (!$name) {
            throw new Exception('Der Name fehlt!');
        } else {
            echo 'Hello ' . $name;
        }
    }
}

$object = new TestClass;

try {
    $object->sayHello('Julian');
    $object->sayHello('');
    $object->sayHello('David');
} catch (Exception $error) {
    echo 'Exception abgefangen: ' . $error->getMessage();
}

echo 'Schönen Tag wünsche ich!';

Wir haben also eine Klasse TestClass. Diese besitzt eine Methode sayHello die uns freundlicherweise begrüßt wenn wir Ihr als Parameter einen Namen mit übergeben. Nette Methode oder ? Doch wenn wir Ihr unseren Namen nicht veraten ist das recht unfreundlich, daher wird Sie uns auch nicht Hallo sagen sondern wird mit einem Fehler schmeißen und uns darauf aufmerksam machen wollen!

Wir instanzieren also ein Objekt der Klasse TestClass. Dann kommt der try Block in dem wir unseren Code schreiben in dem wir evtl einen Fehler vermuten würden. Wir rufen die Methode sayHello auf und übergeben Ihr einen Namen “Julian”. “Julian”, in dem Fall ich, wird begrüßt! Dann rufen wir die Methode auf vergessen Ihr aber unseren Namen zu sagen! Oh Oh… Was macht die Methode, Sie wirft per throw eine Exception! Unser try catch Block bekommt davon sofort Wind und fängt diesen Fehler per catch ab!

Wie sieht unsere Ausgabe eigentlich aus ?

Hello Julian
Exception abgefangen: Der Name fehlt!
Schönen Tag wünsche ich!

Aber hey, ich habe nachdem ich bemerkt habe das ich meinen Namen vergessen hab doch direkt einen weiteren Aufruf hingeknallt! Warum wird David also nicht begrüßt ? Das ist ganz einfach! Nachdem in einem try Block eine Exception geworfen wurde wird innerherhalb des try Blocks nichts mehr ausgeführt! Der try Block wird also sofort verlassen und der rest des Scripts wird ausgeführt, daher wird uns also noch ein schöner Tag gewünscht!

Gut das Beispiel ist etwas blöd um den Sinn hinter dem Exception Handling zu demonstieren weil in diesem Beispiel hätten wir ja auch alles einfach über eine if else Bedingung steuern können. Exception Handling ist eigentlich auch nichts anderes wenn man es man grob betrachtet. Aber es bringt doch etliche Vorteile mit! Man braucht sich nicht mehr um Rückgabewerte kümmern, man schmeisst per throw einfach den Fehler! In etwas komplexeren Szenen kommt dort der Sinn und Zweck schon deutlich zum Vorschein! Würdet Ihr mit dem if Konstrukt arbeiten würdet Ihr sehr schnell in einem tiefen verschachtelten Dschungel landen :-)

Wollt Ihr verschiedene Arten von Fehlern behandeln, empfiehlt es sich, mit unterschiedlichen Fehlerklassen zu arbeiten. Höö?
Ja Ihr werdet staunen, aber wir können sehr einfach eigene Exception Klassen erstellen. Beispiel:

class unfreundlicherUser extends Exception {
    public function __construct($message) {
        parent::__construct($message);
    }
}

Wichtig dabei ist das a) unsere Klasse von der Basisklasse Exception erbt und b) das wir einen Konstruktor definieren damit die Fehlermeldung aufgenommen werden kann!
Unseren obigen Code könnten wir also wie folgt ändern, Ausgangsbasis ist, das uns der User verarschen will und einfach ein “x” eingibt weil er weiss das er was übergeben muss! Aber unser Programm soll auf eine Eingabe von einem “x” mit einem Fehler um sich schmeißen :-)

class TestClass {

    public function sayHello($name) {
        if (!$name) {
            throw new Exception('Der Name fehlt!');
        } elseif ('x' === $name) {
            throw new unfreundlicherUser('Ah Mr. X will uns seinen Namen nicht veraten!');
        } else {
            echo 'Hello ' . $name;
        }
    }

}

$object = new TestClass;

try {
    $object->sayHello('Julian');
    $object->sayHello('x');
} catch (Exception $error) {
    echo 'Exception abgefangen: ' . $error->getMessage();
} catch (unfreundlicherUser $error) {
    echo 'Exception abgefangen: ' . $error->getMessage();
}

$object->sayHello('David');

Wie wir sehen hat sich der Code erweitert. In der Methode sayHello wurde die Abfrage eingebaut wo der Name mit dem “x” verglichen wird. Hat der User also nur ein “x” eingegeben wird eine Exception vom Typ unfreundlichenUser geschmissen die wir vorher selbst definiert haben. An unseren ersten catch Block haben wir einen weiteren gehangen in dem die Fehler vom Typ unfreundlichenUser gefangen werden.

Ist doch super! Wir können also auf alle verschiedenen Fehler verschiedenen reagieren!

In unserem catch Block haben wir nebem getMessage noch mehrere Methoden die uns zur Verfügung stehen.
Darunter zählen

– getCode() zur Ausgabe eines Fehlercodes
– getFile() zur Ausgabe des Dateinamens in dem der Fehler geschmissen wurde
– getLine() die Zeile in dem der Fehler geschmissen wurde
– getTrace() liefert ein Array mit dem Stacktrace
– getTraceAsString() liefert den Stacktrace nicht als Array sondern als String

Wir sehen, es stehen uns reichlich Mittel zur Verfügung um auf jeden Fehler zu reagieren!

Ich hoffe mein Kollege David konnte sich mit dem Thema Exceptions jetzt ein wenig anfreunden und wird es in Zukunft in allen Projekten einsetzen :-)
Ich bin gespannt hehe… und euch hat es hoffentlich auch gefallen! Ein Kommentar und eine Bewertung hier unten würde mich wie immer freuen!

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn
  • Pingback: Julian Kleinhans()

  • Pingback: Alex Kellner()

  • Guter Artikel 😉
    Aber das in meinen nächsten Skripten zu nutzen… hmmm… ich weiss ja nicht so recht 😉

    Cu David

  • das ist aber schoen, danke

  • Tremendous issues on blog.kj187.de . I am very satisfied to peer your article. Thanks a lot and i am looking ahead to touch you. Will you kindly drop me a mail?