Fehlerbehandlung
Seit Typo 4.5.x hat sich die Fehlerbehandlung grundlegend verändert. Es gibt nun in der Regel (PHP) Exceptions bei auftretenden Fehlern. Diese zeigen das TYPO3 Logo auf dem Kopf und "Oops ein Fehler ist aufgetreten". Ich möchte aber alle Fehler abfangen und im Design der Website auf einer Fehlerseite anzeigen. Hier im Detail wie das zu realisieren ist.
Normale 404 Fehler
Normale 404 Fehler kann man abfangen durch den Eintrag in localconf.php
$TYPO3_CONF_VARS['FE']['pageNotFound_handling'] ='REDIRECT:pagenotfound.html';
Damit wird ein Seite in TYPO3 angezeigt im korrekten Design.
Skript
Was aber in TYPO3 4.6 nicht mehr geht ist das Skript bei Fehlern:
$TYPO3_CONF_VARS['FE']['pageNotFound_handling'] ='USER_FUNCTION:scripts/pageNotFoundHandling.php:user_pageNotFound->pageNotFound';
Hier kommt der Fehler:
Fatal error: Call to a member function getRootLine() on a non-object in /Users/erwin/iPool/htdocs/_typo3/typo3_src-4.6.0/typo3/sysext/cms/tslib/class.tslib_fe.php on line 1188
Exceptions
Wenn man nun aber z.B. Einen Controller mit einer ungültigen Action aufruft kommt die Oops Seite mit detaillierter Fehlermeldung wenn man im BE eingeloggt ist, und ohne wenn nicht. Aber möchte ich eigentlich eine Seite im Design der Website anzeigen.
Wenn man in der localconf.php setzt
$TYPO3_CONF_VARS['SYS']['displayErrors'] = '0';
$TYPO3_CONF_VARS['SYS']['productionExceptionHandler'] = '';
wird eine leere weisse Seite ohne jedes html angezeigt, was auch nicht besser ist.
Hier findet man auf TYPO3.org den Hinweis man könne einen eigenen FehlerHandler schreiben (http://typo3.org/documentation/document-library/core-documentation/doc_core_api/4.3.1/view/8/2), aber wie genau das klappen soll steht nirgendwo genauer - aber es ist mir nun doch gelungen.
Eigener Exception Handler
Zunächst in localconf.php:
# full path required to prevent errors in backend
include "/httpdocs/developer/fileadmin/scripts/RsysProductionExceptionHandler.php";
$TYPO3_CONF_VARS['SYS']['productionExceptionHandler'] = 'RsysProductionExceptionHandler';
In RsysProductionExceptionHandler.php habe ich alle Methoden aus t3lib/error/class.t3lib_error_abstractexceptionhandler.php und t3lib/error/class.t3lib_error_productionexceptionhandler.php zusammenkopiert in eine Datei sowie die Methode echoExceptionWeb() überschrieben mit:
class RsysProductionExceptionHandler {
...
public function echoExceptionWeb(Exception $exception) {
$redirectUrl = "pagenotfound.html";
header("HTTP/1.0 404 Not Found");
header ("Location: $redirectUrl");
}
}
Deprecated Fehler
Diese wird man los indem man sie als "exceptionalErrors" deklariert mit:
$TYPO3_CONF_VARS['SYS']['productionExceptionHandler'] = 't3lib_error_ProductionExceptionHandler';
$TYPO3_CONF_VARS['SYS']['exceptionalErrors'] = E_ALL ^ E_NOTICE ^ E_WARNING ^ E_USER_ERROR ^ E_USER_NOTICE ^ E_USER_WARNING ^ E_DEPRECATED;
Exceptions innerhalb der Extension
Hier kann man eine eigene Fehlerbehandlung programmieren, die aber nur für Fehler greift, die man selbst auslöst mit Absicht innerhalb der Extension. Wie das geht steht gut beschrieben in der Mittwald Dokumentation "Extbase und Fluid Dokumentation" zu finden unter http://www.mittwald.de/extbase-dokumentation.
AbstractController
Kurz beschrieben: ich habe eine neue Controllerklasse angelegt: AbstractController.php
Abstract Class Tx_Rsysproductbase_Controller_AbstractController Extends Tx_Extbase_MVC_Controller_ActionController {
Alle Controller leiten sich davon ab - auch automatisch mit folgenden Eintrag in Configuration/ExtensionBuilder/settings.yaml:
classBuilder:
Controller:
parentClass: Tx_Rsysproductbase_Controller_AbstractController
Ich fange zunächst mal alle Fehler innerhalb einer Action ab mit Überschreiben von callActionMethod:
Protected Function callActionMethod() {
Try {
parent::callActionMethod();
} Catch(Exception $e) {
if($this->settings['settings']['Debug']) {
$this->response->appendContent( 'Es ist ein Fehler aufgetreten<br><span class="debug">Debug Fehler:<br>' . $e->getMessage() . '</span>');
} else {
$this->response->appendContent( 'Es ist ein Fehler aufgetreten');
}
}
}
Um den Debug Modus zu setzen folgendes TS:
plugin.tx_rsysproductbase {
settings {
Debug = 1
}
Alternative
Es gibt ein undokumentiertes Feature um einen 404 Fehler auszulösen bei ungültigen Aktionen:
plugin.tx_rsysproductbase {
mvc {
throwPageNotFoundExceptionIfActionCantBeResolved = 1
}
Nachteil gegenüber obiger Lösung ist, dass man hier die Fehlermeldung (im Debugmodus) nicht ausgeben kann.
Fehlereinstellungen Produktivumgebung
Weitgehend alles logging abschalten und Userfreundliche Fehlerseiten anzeigen kann man mit folgenden Einstellungen in der localconf.php (und allen weiter oben beschriebenen Änderungen):
# be quiet !!!
$TYPO3_CONF_VARS['SYS']['enableDeprecationLog'] = '0';
$TYPO3_CONF_VARS['SYS']['displayErrors'] = '0';
$TYPO3_CONF_VARS['SYS']['systemLog'] = '';
$TYPO3_CONF_VARS['SYS']['systemLogLevel'] = '';
$TYPO3_CONF_VARS['BE']['allowDonateWindow'] = '0';
$TYPO3_CONF_VARS['SYS']['errorHandlerErrors'] = '0';
$TYPO3_CONF_VARS['SYS']['syslogErrorReporting'] = '0';
$TYPO3_CONF_VARS['SYS']['belogErrorReporting'] = '0';
$TYPO3_CONF_VARS['SYS']['exceptionalErrors'] = E_ALL ^ E_NOTICE ^ E_WARNING ^ E_USER_ERROR ^ E_USER_NOTICE ^ E_USER_WARNING ^ E_DEPRECATED;
# rsys handler
include "fileadmin/scripts/RsysProductionExceptionHandler.php";
$TYPO3_CONF_VARS['SYS']['productionExceptionHandler'] = 'RsysProductionExceptionHandler';