# Zend_Controller_Plugin_ErrorHandler

`Zend_Controller_Plugin_ErrorHandler` est un plugin intégré par défaut pour gérer les exceptions levées par votre application, il sert à gérer les exceptions envoyées par l'application, en particulier celles concernant des contrôleurs ou des actions manquants. C'est une manière rejoignant la section Exceptions MVC.

Les principaux objectifs de ce plugin sont :

- Intercepter les exceptions envoyées si aucune route ne correspond

- Intercepter les exceptions envoyées si un contrôleur ou une action ne peuvent être trouvés

- Intercepte les exceptions envoyées dans les contrôleurs

Globalement, ErrorHandler sert à gérer les erreurs HTTP 404 ou 500. Attention, le plugin n'est pas destiné à intervenir sur les exceptions envoyées dans d'autres plugins. Des effets de bords peuvent apparaître, veillez à les gérer.

Par défaut, `Zend_Controller_Plugin_ErrorHandler` redirige vers `ErrorController::errorAction()` dans le module par défaut. Vous pouvez passer d'autres valeurs via les accesseurs du plugin :

- `setErrorHandlerModule()` définit le module à utiliser.

- `setErrorHandlerController()` définit le contrôleur à utiliser.

- `setErrorHandlerAction()` définit l'action à utiliser.

- `setErrorHandler()` est un raccourci des trois précédantes. Passez un tableau avec les clés "module", "controller", or "action", et leurs valeurs appropriées.

Ce comportement fonctionne aussi avec le constructeur du plugin. Celui-ci agit comme un proxy vers `setErrorHandler()`.

`Zend_Controller_Plugin_ErrorHandler` agit en `postDispatch()` et analyse l'objet de réponseà la recherche d'éventuelles exceptions. Si il y en a, alors le plugin modifie la requête pour distribuer le contrôleur et l'action d'erreur.

Si une exception arrive lorsque le plugin agit, alors celui-ci ordonne au contrôleur frontal de renvoyer l'exception, et relance la dernière exception enregistrée dans l'objet de réponse.

## Utilisation de ErrorHandler pour gérer les erreurs 404

Comme ErrorHandler capture les exceptions relatives à un problème de contrôleur ou action manquants, vous pouvez donc l'utiliser comme un gestionnaire d'erreurs 404. Pour cela, il faut analyser le type d'exception ayant mené à l'erreur.

Les exceptions capturées sont enregistrées en tant que paramètre d'action. `Zend_Controller_Action::_getParam('error_handler')`:

    class ErrorController extends Zend_Controller_Action
    {
        public function errorAction()
        {
            $errors = $this->_getParam('error_handler');
        }
    }

Une fois que vous possédez l'objet contenant l'exception, inspectez son type avec `$errors->type;`. Des constantes sont à votre disposition :

- `Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE`, indique qu'aucune route correspondante n'a été trouvée.

- `Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER`, indique un contrôleur non trouvé.

- `Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION`, indique qu'une action est absente.

- `Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER`, indique une autre exception.

Les trois premiers types pourraient mener à une erreur 404 :

    class ErrorController extends Zend_Controller_Action
    {
        public function errorAction()
        {
            $errors = $this->_getParam('error_handler');

            switch ($errors->type) {
                case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
                case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
                case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
                    // erreur 404 -- contrôleur ou action introuvable
                    $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');

                    // ... ici, de l'affichage (du rendu)
                    break;
                default:
                    // erreur applicative; affiche une page d'erreur,
                    // mais sans changer le code de retour HTTP
                    break;
            }
        }
    }

Enfin, il est possible de récupérer l'exception ayant menée au contrôleur d'erreur. Ceci afin de l'analyser. L'attribut exception de l'objet error_handler le permet :

    public function errorAction()
    {
            $errors = $this->_getParam('error_handler');

            switch ($errors->type) {
                case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
                case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
                case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
                    // erreur 404 -- contrôleur ou action introuvable
                    $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');

                    // ... ici, de l'affichage (du rendu)
                    break;
                default:
                    // erreur applicative; affiche une page d'erreur,
                    // mais sans changer le code de retour HTTP

                    // ...

                    // Sauve l'exception en log:
                    $exception = $errors->exception;
                    $log =
                        new Zend_Log(
                            new Zend_Log_Writer_Stream(
                                '/tmp/applicationException.log')
                        );
                    $log->debug($exception->getMessage()
                              . "\n"
                              . $exception->getTraceAsString());
                    break;
            }
    }

## Gestion des rendus précédants de la réponse

Si vous décomposez vos processus en plusieurs actions ou plusieurs appels à `render()`, il est possible que la réponse contienne déjà des éléments. Ceci peut introduire un mélange entre le rendu attendu et le contenu de l'erreur.

Si vous désirez rendre votre contrôleur d'erreur dans ce contenu, alors il n'y a rien à faire de spécial. En revanche, il peut aussi être judicieux de vider totalement la réponse afin de rendre le contrôleur d'erreurs. Procédez alors comme suit :

    $this->getResponse()->clearBody();

## Exemples d'utilisation

### Utilisation standard et désactivation

    $front = Zend_Controller_Front::getInstance();
    $front->registerPlugin(new Zend_Controller_Plugin_ErrorHandler());

### Paramétrage du plugin

    $front = Zend_Controller_Front::getInstance();
    $front->registerPlugin(new Zend_Controller_Plugin_ErrorHandler(array(
        'module'     => 'mystuff',
        'controller' => 'static',
        'action'     => 'error'
    )));

### Utilisation des accesseurs

    $plugin = new Zend_Controller_Plugin_ErrorHandler();
    $plugin->setErrorHandlerModule('mystuff')
           ->setErrorHandlerController('static')
           ->setErrorHandlerAction('error');

    $front = Zend_Controller_Front::getInstance();
    $front->registerPlugin($plugin);

## Exemple de contrôleur d'erreurs

Pour utiliser le plugin de gestion d'erreurs, un contrôleur d'erreurs est requis. En voici un exemple :

    class ErrorController extends Zend_Controller_Action
    {
        public function errorAction()
        {
            $errors = $this->_getParam('error_handler');

            switch ($errors->type) {
                case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
                case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
                case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
                    // 404 error -- controller or action not found
                    $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');

                    $content =<<<EOH
    <h1>Erreur !</h1>
    <p>Page introuvable.</p>
    EOH;
                    break;
                default:
                    // application error
                    $content =<<<EOH
    <h1>Erreur !</h1>
    <p>Une erreur innatendue est survenue</p>
    EOH;
                    break;
            }

            // Vide le contenu de la réponse
            $this->getResponse()->clearBody();

            $this->view->content = $content;
        }
    }