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.
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 pagecontroller.php genutzt werden:
import('my::project', 'CustomExceptionHandler');
GlobalExceptionHandler::registerExceptionHandler(new CustomExceptionHandler());Sofern notwendig, können Sie der Instanz des ExceptionHandler beliebige Informationen (z.B. Context) mitgeben.
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 pagecontroller.php erledigen:
// Deaktivieren der APF Exception-Behandlung
GlobalExceptionHandler::disable();
// Erneute Aktivierung der APF Exception-Behandlung
GlobalExceptionHandler::enable();Um eine eigene Exception-Behandlung einzuführen, muss das Interface ExceptionHandler implementiert werden. Diese definiert die folgende Methode:
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:
class CustomExceptionHandler implements ExceptionHandler {
private $context;
public function __construct($context) {
$this->context = $context;
}
public function handleException(Exception $exception) {
...
}
}
GlobalExceptionHandler::registerExceptionHandler(new CustomExceptionHandler('foo'));Als Implementierungsbeispiele für eigene ExceptionHandler können Sie die Klassen DefaultExceptionHandler und ProductionExceptionHandler heranziehen.
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
throw new Exception();zu platzieren und diese anschließend nicht anzufangen.
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.
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 pagecontroller.php wie folgt vorgenommen werden:
import('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.
Die Entwicklung des APF wird von JetBRAINS mit PHPStorm-Lizenzen unterstützt und wir sind überzeugt davon, dass PHPStorm die Qualität nachhaltig steigert. Benutzen auch Sie PHPStorm!
Proud to useIntelligent PHP IDE for coding, testing and debugging with pleasure