Zend_Controller_Plugins_ErrorHandler Zend_Controller_Plugins_ErrorHandler представляет собой плагин для обработки исключений, брошенных вашим приложением, включая те, которые вызваны отсутствием запрошенного контроллера или действия. Он является альтернативой способам, перечисленным в разделе об исключениях MVC. Основные назначения этого плагина: Перехват исключений, вызванных отсутствием контроллера или метода действия Перехват исключений, брошенных в контроллерах действий Другими словами, плагин ErrorHandler спроектирован для обработки HTTP-ошибок типа 404 (отсутствует страница) и 500 (внутренняя ошибка). Он не предназначен для отлова исключений, сгенерированных в других плагинах или в процессе маршрутизации. По умолчанию Zend_Controller_Plugins_ErrorHandler будет производить переход к ErrorController::errorAction() в модуле по умолчанию. Вы можете установить альтернативные значения для перехода, используя набор методов-аксессоров, доступных в плагине: setErrorHandlerModule() устанавливает модуль, на который производится переход. setErrorHandlerController() устанавливает контроллер, на который производится переход. setErrorHandlerAction() устанавливает действие, на которое производится переход. setErrorHandler() принимает ассоциативный массив, который может содержать любые из ключей 'module', 'controller' или 'action'. Кроме этого, вы можете опционально передать конструктору ассоциативный массив, который будет в свою очередь передан setErrorHandler(). Zend_Controller_Plugin_ErrorHandler регистрирует перехватчик postDispatch() и проверяет, есть ли зарегистрированые исключения в объекте ответа. Если есть, то производится попытка перехода на действие, зарегистрированное в качестве обработчика ошибок. Если во время диспетчеризации обработчика ошибок произошло исключение, то плагин скажет фронт-контроллеру, чтобы тот бросил исключения, и повторно бросит последнее исключение, зарегистрированное в объекте ответа. Использование ErrorHandler в качестве обработчика ошибки 404 Поскольку плагин захватывает не только ошибки приложения, но и ошибки в цепочке контроллеров, вызванные отсутствием класса контроллера и/или метода действия, то он может использоваться в качестве обработчика ошибки 404. В этом случае нужно, чтобы ваш контроллер ошибок проверял тип исключения. Перехваченные исключения журналируются в объекте, зарегистрированном в запросе. Для его получения используйте метод Zend_Controller_Action::_getParam('error_handler'): _getParam('error_handler'); } } ]]> Имея объект ошибки, вы можете получить тип ошибки через $errors->type. Тип ошибки может быть одним из следующих: Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER, означает, что контроллер не был найден. Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION, означает, что запрошенное действие не было найдено. Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER, обозначает другие исключения. Вы можете производить проверку на первые два типа и в случае положительного ответа указывать страницу 404: _getParam('error_handler'); switch ($errors->type) { case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: // ошибка 404 - не найден контроллер или действие $this->getResponse() ->setRawHeader('HTTP/1.1 404 Not Found'); // ... получение данных для отображения... break; default: // ошибка приложения; выводим страницу ошибки, // но не меняем код статуса break; } } } ]]> Вы можете извлекать исключение, которое инициировало вызов обработчика ошибок, через свойство exception объекта error_handler: _getParam('error_handler'); switch ($errors->type) { case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: // ошибка 404 - не найден контроллер или действие $this->getResponse() ->setRawHeader('HTTP/1.1 404 Not Found'); // ... получение данных для отображения... break; default: // ошибка приложения; выводим страницу ошибки, // но не меняем код статуса // ... // Журналируем исключение: $exception = $errors->exception; $log = new Zend_Log( new Zend_Log_Writer_Stream( '/tmp/applicationException.log' ) ); $log->debug($exception->getMessage() . "\n" . $exception->getTraceAsString()); break; } } ]]> Управление сгенерированным ранее выводом Если в процессе обработки запроса вызывается несколько действий, или ваше действие несколько раз вызывает метод render(), то возможно, что объект ответа уже содержит в себе сохраненные данные для вывода. Это может привести к тому, что выведется смесь из ожидаемого содержимого и содержимого ошибки. Если вы хотите, чтобы сообщения об ошибках выводились на этих же страницах, то нет необходимости что-либо менять. В противном случае следует очистить тело ответа до того, как производить рендеринг каких-либо видов: getResponse()->clearBody(); ]]> Примеры использования плагина Стандартное использование registerPlugin(new Zend_Controller_Plugin_ErrorHandler()); ]]> Установка другого обработчика ошибок registerPlugin(new Zend_Controller_Plugin_ErrorHandler(array( 'module' => 'mystuff', 'controller' => 'static', 'action' => 'error' ))); ]]> Использование аксессоров setErrorHandlerModule('mystuff') ->setErrorHandlerController('static') ->setErrorHandlerAction('error'); $front = Zend_Controller_Front::getInstance(); $front->registerPlugin($plugin); ]]> Пример контроллера ошибок Для того, чтобы использовать плагин ErrorHandler, нужен контроллер ошибок. Ниже приводится простой пример такого контроллера. _getParam('error_handler'); switch ($errors->type) { case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: // ошибка 404 - не найден контроллер или действие $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found'); $content =<<Ошибка!

Запрошенная вами страница не найдена.

EOH; break; default: // ошибка приложения $content =<<Ошибка!

Произошла непредвиденная ошибка. Пожалуйста, попробуйте позднее.

EOH; break; } // Удаление добавленного ранее содержимого $this->getResponse()->clearBody(); $this->view->content = $content; } } ]]>