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.

Erstellt: 11/2011| Geändert: 10/2015

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

Erstellt: 11/2011| Geändert: 10/2015

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");
}
}

Erstellt: 11/2011| Geändert: 10/2015

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;

Erstellt: 11/2011| Geändert: 10/2015

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.

Erstellt: 11/2011| Geändert: 10/2015

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'; 

 

Erstellt: 11/2011| Geändert: 10/2015