0 follower

Fehlerbehandlung

Yii bietet ein vollständiges Framework zur Fehlerbehandlung, das auf dem Exception-Mechanismus von PHP 5 basiert. Wenn eine Applikation erzeugt wird, um einen eingehenden Benutzer-Request zu bearbeiten, registriert sie ihre handleError-Methode (sinngem.: behandle Fehler), um PHPs Warnungen und Hinweise zu verarbeiten. Außerdem registriert sie ihre handleException-Methode (sinngem.: behandle Ausnahme), um nicht-abgefangene PHP-Exceptions zu bearbeiten. Wenn daher während der Ausführung der Anwendung eine PHP-Warnung, ein PHP-Hinweis oder eine nicht-abgefangene Exception auftritt, wird eine dieser Fehlerroutinen die Kontrolle übernehmen und die nötige Prozedur zur Bearbeitung des Fehlers einleiten.

Tipp: Die Fehlerroutinen werden im Konstruktor der Anwendung durch Aufruf der PHP-Funktionen set_exception_handler und set_error_handler registriert. Wenn Sie nicht möchten, dass Yii sich um Fehler und Exceptions kümmert, können Sie im Eingangsscript die Konstanten YII_ENABLE_ERROR_HANDLER und YII_ENABLE_EXCEPTION_HANDLER als false definieren.

Per Vorgabe löst errorHandler (bzw. exceptionHandler) ein onError-Event (bzw. onException-Event) aus. Falls der Fehler (bzw. die Exception) von keinem Eventhandler behandelt wird, ruft die Routine die errorHandler-Anwendungskomponente zu Hilfe.

1. Auslösen von Exceptions

Das Auslösen einer Exception (Ausnahme) in Yii unterscheidet sich nicht vom Auslösen einer normalen PHP-Exception. Exceptions werden bei Bedarf mit folgender Syntax ausgelöst:

throw new ExceptionClass('ExceptionNachricht');

Yii definiert zwei Exceptionklassen: CException und CHttpException. Erstere ist eine allgemeine Exceptionklasse, während letztere eine Exception darstellt, die dem Endanwender angezeigt werden soll. Sie hat auch eine statusCode-Eigenschaft, die für den HTTP-Statuscode steht. Wie wir gleich sehen werden, bestimmt die Klasse einer Exception darüber, wie diese angezeigt werden soll.

Tipp: Durch das Auslösen einer CHttpException-Exception kann man sehr einfach auf Fehlfunktionen aufmerksam machen. Falls ein Benutzer z.B. eine falsche Beitrags-ID übergibt, können wir die folgende Anweisung verwenden um einen 404-Fehler (Seite nicht gefunden) auszugeben:

// Falls Beitrags-ID ungültig ist:
throw new CHttpException(404,'Der angegebene Beitrag wurde nicht gefunden.');

2. Anzeigen von Fehlern

Wenn ein Fehler an die Anwendungskomponente CErrorHandler weitergeleitet wird, sucht diese nach dem passenden View, um den Fehler anzuzeigen. Falls der Fehler zur Anzeige für den Endanwender gedacht ist (wie z.B. CHttpException), verwendet sie einen View namens errorXXX, wobei XXX für den HTTP-Statuscode steht (z.B. 400, 404, 500). Falls es sich um einen internen Fehler handelt und dieser nur Entwicklern angezeigt werden soll, verwendet sie einen View namens exception. In letzterem Fall wird der vollständige Aufrufstapel (engl.: call stack) sowie Informationen zur Zeile, in der der Fehler aufgetreten ist, angezeigt.

Info: Falls die Anwendung im Produktivmodus läuft, werden alle (inkl. interne) Fehler mit dem View errorXXX angezeigt, da der Aufrufstapel evtl. sensible Daten enthalten kann. In diesem Fall sollte der Entwickler Fehlerprotokolle verwenden, um die wahre Ursache des Fehlers herauszufinden.

CErrorHandler sucht in dieser Reihenfolge nach der entsprechenden View-Datei:

  1. WebRoot/themes/MotivName/views/system: dies ist das Verzeichnis für system-Views im gerade aktiven Motiv (engl: theme).

  2. WebRoot/protected/views/system: dies ist das Standardverzeichnis für system-Views einer Anwendung.

  3. yii/framework/views: dies ist das Standardverzeichnis für system-Views, die das Yii-Framework bereitstellt.

Wenn wir also die Darstellung der Fehler anpassen möchten, können wir einfach im system-View-Verzeichnis unserer Anwendung oder unseres Motivs View-Dateien anlegen. Jede View-Datei ist ein gewöhnliches PHP-Script, das hauptsächlich aus HTML-Code besteht. Mehr Details finden sie in den vorgegebenen View-Dateien im view-Verzeichnis des Frameworks.

Fehlerbehandlung mit einer Action

Seit Version 1.0.6 erlaubt Yii die Verwendung einer Controller-Action zur Anzeige eines Fehlers. Dazu müssen wir die Fehlerroute in der Anwendungskonfiguration wie folgt konfigurieren:

return array(
    ......
    'components'=>array(
        'errorHandler'=>array(
            'errorAction'=>'site/error',
        ),
    ),
);

Hier setzen wir die CErrorHandler::errorAction-Eigenschaft auf die Route site/error, was sich auf die error-Action in SiteController bezieht. Bei Bedarf können wir auch eine andere Route verwenden.

Die error-Action können wir wie folgt schreiben:

public function actionError()
{
    if($error=Yii::app()->errorHandler->error)
        $this->render('error', $error);
}

In der Action holen wir uns zunächst die detaillierte Fehlerinformationen aus CErrorHandler::error. Falls diese nicht leer ist, wird der error-View zusammen mit den Fehlerinformationen gerendert. Die von CErrorHandler::error zurückgegebene Fehlerinformation ist ein Array mit den folgenden Feldern:

  • code: der HTTP-Statuscode (z.B. 403, 500);
  • type: der Fehlertyp (z.B. CHttpException, PHP Error);
  • message: die Fehlernachricht;
  • file: der Name des PHP-Scripts, in dem der Fehler aufgetreten ist;
  • line: die Nummer der Zeile, in der der Fehler aufgetreten ist;
  • trace: der Aufrufstapel des Fehlers;
  • source: der Quelltextbereich, in dem der Fehler aufgetreten ist.

Tipp: Die Prüfung, ob CErrorHandler::error leer ist oder nicht, führen wir durch, da die error-Action auch direkt von einem Endbenutzer aufgerufen werden könnte. In diesem Fall gibt es aber keinen Fehler. Da wir das $error-Array direkt an den View übergeben, wird es automatisch in einzelne Variablen expandiert. Daher können wir im View die Variablen direkt als $code, $type usw. ansprechen.

3. Loggen von Nachrichten

Immer wenn ein Fehler auftritt, wird eine Nachricht mit der Stufe error geloggt. Falls der Fehler von einer PHP-Warnung oder einem PHP-Hinweis stammt, wird die Nachricht mit der Kategorie php geloggt. Stammt der Fehler von einer nicht-abgefangenen Exception, lautet die Kategorie exception.ExceptionKlassenName (bei CHttpException wird auch deren statusCode an die Kategorie angehängt). Man kann somit die Verfahren zur Protokollierung benutzen, um Ausführungsfehler einer Anwendung zu überwachen.