Exception-Behandlung

1. Einleitung

Analog zu Fehlerbehandlung verfügt das APF ebenfalls über einen globalen Mechanismus zur Behandlung von in der Applikation nicht abgefangenen Exceptions. Auch in diesem Fall wird eine Fehlerseite angezeigt, die alle Parameter der Exception sowie einen Stacktrace beinhaltet.

Die Architektur der APF-Exception-Behandlung ist identisch zur Fehler-Behandlung und wird über den zentralen Anlaufpunkt GlobalExceptionHandler gesteuert. Dieser nimmt eine Exception entgegen und delegiert die Behandlung an den registrierten ExceptionHandler. Dieser Mechanismus lässt sich sehr einfach dazu nutzen um schwerwiegende Exceptions (z.B. der Abbruch einer Verbindung zu einem Middle-Tier-System) zentral behandeln zu können. Hierdurch verschlankt sich zudem der Quellcode einer konkreten Funktionalität.

Das Interface ExceptionHandler besitzt eine zusätzliche Standard-Implementierungen (siehe unten) und kann jederzeit dazu genutzt werden, Implementierungen für den eigenen Anwendungsfall zu schaffen.

2. Konfiguration

2.1. Eigener ExceptionHandler

Der GlobalExceptionHandler ist im Auslieferungszustand des APF bereits aktiviert. Als Standard-Handler ist der DefaultExceptionHandler registriert.

Um den vorkonfigurierten Zustand durch einen eigenen zu ersetzen kann folgender Code nach dem Einbinden der bootstrap.php genutzt werden:

PHP-Code
use VENDOR\project\CustomExceptionHandler; GlobalExceptionHandler::registerExceptionHandler(new CustomExceptionHandler());

Sofern notwendig, können Sie der Instanz des ExceptionHandler beliebige Informationen (z.B. Context) mitgeben.

2.2. Aktivierung und Deaktivierung

Soll der APF-Mechamismus deaktiviert oder nach einer Deaktivierung wieder aktiviert werden, so können Sie dies mit Hilfe des GlobalExceptionHandler sehr einfach nach dem Einbinden der bootstrap.php erledigen:

PHP-Code
// Deaktivieren der APF Exception-Behandlung GlobalExceptionHandler::disable(); // Erneute Aktivierung der APF Exception-Behandlung GlobalExceptionHandler::enable();

3. Implementierung eines ExceptionHandler

Um eine eigene Exception-Behandlung einzuführen, muss das Interface ExceptionHandler implementiert werden. Diese definiert die folgende Methode:

PHP-Code
interface ExceptionHandler { public function handleException(Exception $exception); }

Bei Auftreten einer Exception wird diese an die Methode handleException() übergeben.

Da die Exception-Behandlung in einer eigenen Klasse (z.B. DefaultExceptionHandler) stattfindet, die nicht mit dem ServiceManager erzeugt wurde, steht der Zugriff auf den aktuellen Context und die aktuelle Sprache nicht zur Verfügung!

Werden diese Informationen benötigt, können Sie Ihrer Implementierung beliebige Attribute über den Konstruktor oder getter-Methoden mitgeben. Beispiel:

PHP-Code
use APF\core\exceptionhandler\GlobalExceptionHandler; use APF\core\exceptionhandler\ExceptionHandler; class CustomExceptionHandler implements ExceptionHandler { private $context; public function __construct($context) { $this->context = $context; } public function handleException(Exception $exception) { ... } } use VENDOR\project\CustomExceptionHandler; GlobalExceptionHandler::registerExceptionHandler(new CustomExceptionHandler('foo'));

Als Implementierungsbeispiele für eigene ExceptionHandler können Sie die Klassen DefaultExceptionHandler und ProductionExceptionHandler heranziehen.

4. Anwendung

Der globale Exception-Behandlungsmechanismus greift immer dann, wenn eine Exception im Applikationscode nicht behandelt wird. Dies kann konzeptionell absichtlich vorgesehen sein um Exceptions oder unerwartet auftreten.

Sollte unabsichtlich eine Exception auftreten, so handelt es sich dabei meist um eine Exception während der Entwicklung. Hier bietet die angezeigte Fehler-Seite ausreichend Informationen um den Grund zu analysieren.

Die konzeptionelle Nutzung des Mechanismus bietet sich immer dann an, wenn eine Exception einen Zustand repräsentiert, der von der Applikation nicht sinnvoll abgefangen werden kann (z.B. Verbindungsabbruch zu einem Middle-Tier-System). Hier kann beispielsweise der ProductionExceptionHandler genutzt werden um den Benutzer auf eine dedizierte Fehler-Seite zu lenken.

Um den Mechanismus zu triggern, genügt es im Code die Zeile

PHP-Code
throw new Exception();

zu platzieren und diese anschließend nicht anzufangen.

5. Verfügbare ExceptionHandler

Das APF bringt mit dem ProductionExceptionHandler eine weitere ExceptionHandler-Implementierungen mit. Diese ist für den Einsatz in Live-Umgebungen gedacht. Live-Systeme gilt es im besonderen vor Kompromittierung zu schützen. Daher ist der ProductionExceptionHandler dafür ausgelegt, möglichst die bei einem Fehler gesammelten Daten vor dem potentiellen Angreifer zu verstecken. Eine weitere Implementierung ist der CLIExceptionHandler für die Fehlerausgabe in der Konsole.

5.1. ProductionExceptionHandler

Tritt eine Exception auf, fügt der ProductionExceptionHandler diesen an die globale Log-Datei an und leitet auf eine zuvor konfigurierte Seite weiter. Damit schützt er vor der Veröffentlichung von Daten, die zum Zeitpunkt des Fehlers gesammelt wurden.

Die Konfiguration kann nach Einbinden der Datei bootstrap.php wie folgt vorgenommen werden:

PHP-Code
use APF\core\exceptionhandler\GlobalExceptionHandler; use APF\core\exceptionhandler\ProductionExceptionHandler; Registry::register('APF\core\exceptionhandler', 'ProductionExceptionRedirectUrl', '/pages/global-error'); GlobalExceptionHandler::registerExceptionHandler(new ProductionExceptionHandler());

Der Registry-Schlüssel Argument definiert diejenige Url zu der der Benutzer im Falle eines Fehlers weitergeleitet wird.

Bitte stellen Sie sicher, dass die Fehlerseite keine weiteren Exceptions produziert. Andernfalls erzeugen Sie dadurch eine Umleitungsschleife, die keine Abbruchbedingung besitzt!

5.2. CLIExceptionHandler

Der CLIExceptionHandler ermöglicht eine Fehlerausgabe in der Konsole, da keine HTML-Elemente zur Formatierung der Ausgabe eingesetzt werden.

Die Einbindung des CLIExceptionHandler gestaltet sich wie folgt:

Code
use APF\core\exceptionhandler\GlobalExceptionHandler; use APF\core\exceptionhandler\CLIExceptionHandler; GlobalExceptionHandler::registerExceptionHandler( new CLIExceptionHandler() );

Dadurch werden alle Fehler ohne HTML-Elemente ausgegeben. Die Fehlerausgabe sind dann beispielsweise wie folgt aus:

Code
[90a92a2482930a4025a4c6409461b241][8] Undefined index: Value /var/www/index.php:25 Stacktrace: Foo->doSomething() /var/www/index.php:19

Kommentare

Möchten Sie den Artikel eine Anmerkung hinzufügen, oder haben Sie ergänzende Hinweise? Dann können Sie diese hier einfügen. Die bereits verfassten Anmerkungen und Kommentare finden Sie in der untenstehenden Liste.
Für diesen Artikel liegen aktuell keine Kommentare vor.