Thanks for explaining this stuff, Gog!
Now my errors appear to be getting passed to the error handler. All is well with the world.
Chris
First you have to make sure you can navigate to the error controller with your browser via http://localhost/error/error or http://localhost/default/error/error
If you get an "Object not found" error than you have to check your Apache httpd.conf and comment out:
# Multi-language error messages
#Include conf/extra/httpd-multilang-errordoc.conf
because of this directive Apache maps /error to path_to_your_apache_installation/error folder, and not through the .htaccess file to index.php
After you are sure that you ErrorController is working (you also need a scripts/error/error.phtml file), and it' accessible just make sure that you haven't set $frontController->throwExceptions(true) on your Front Controller, because it disables the ErrorHandler controller plugin.
p.s.
You don't need to register Zend_Controller_Plugin_ErrorHandler () with the Front controller using something like $frontController->registerPlugin (new Zend_Controller_Plugin_ErrorHandler ()); because the Zend_Controller_Plugin_ErrorHandler () is enabled by default.
Hope this helps...
Last edited by gog; 07-16-2008 at 10:54 AM. Reason: typo
Thanks for explaining this stuff, Gog!
Now my errors appear to be getting passed to the error handler. All is well with the world.
Chris
Hi mate,
thanks heaps for the response, did everything you mentioned. I can access my error controller directly and it displays fine but it just doesn't get wanna wake up to an error.
Below is what my front controller looks like:
But when I try a non-existent path 'mysite/fakecontroller' to invoke the error controller I see: Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (fakecontroller)' in ...Code:<?php error_reporting(E_ALL|E_STRICT); set_include_path( '.' . PATH_SEPARATOR . '../../libraries' . PATH_SEPARATOR . '../../systems/admin/models' . PATH_SEPARATOR . '../../access/admin/widgets' . PATH_SEPARATOR . '../../elements' . PATH_SEPARATOR . get_include_path()); include "Zend/Loader.php"; Zend_Loader::registerAutoload(); $systemConfig = new Zend_Config_Ini('../../../configuration/system.ini', 'development'); $registry = Zend_Registry::getInstance(); $registry->set('system_config', $systemConfig); $db = Zend_Db::factory($systemConfig->db); Zend_Db_Table::setDefaultAdapter($db); Zend_Registry::set('db', $db); $frontController = Zend_Controller_Front::getInstance(); $frontController->setControllerDirectory('../../systems/admin/controllers'); $router = $frontController->getRouter(); $router->addRoute('app', new Zend_Controller_Router_Route('apps/:appname', array('controller' => 'apps', 'action' => 'index'))); Zend_Layout::startMvc(array('layoutPath'=>'../../systems/admin/layouts'));$frontController->dispatch();
Can you please send me a working implementation of error controller? thanks.
Here's whats in my bootstrap.php:
Then I've got a Controller called ErrorController.phpCode:<?php error_reporting(E_ALL | E_STRICT); ini_set('display_startup_errors', 1); ini_set('display_errors', 1); date_default_timezone_set('Australia/Melbourne'); set_include_path('.' . PATH_SEPARATOR . '../library/' . PATH_SEPARATOR . '../application' . PATH_SEPARATOR . '../application/models' . PATH_SEPARATOR . get_include_path()); include "Zend/Loader.php"; Zend_Loader::registerAutoload(); $config = new Zend_Config_Ini('../application/config.ini', 'default'); $registry = Zend_Registry::getInstance(); $registry->set('config', $config); Zend_Layout::startMvc($config->appearance); $frontController = Zend_Controller_Front::getInstance(); $frontController->throwExceptions(false); $frontController->setControllerDirectory('../application/controllers'); $frontController->setBaseUrl('/'); $frontController->dispatch();
All mine has in it is:
Then inside of: views->scripts->error i've got a page called error.phtmlCode:<?php class ErrorController extends Zend_Controller_Action { public function init() { $this->view->baseUrl = $this->_request->getBaseUrl(); } public function errorAction() { $this->view->title = "Error Page"; } }
And all that contains is a custom error message.
In my bootstrap I just change the flag in $frontController->throwExceptions(false); to true when I'm debugging.
Al
I'm also pretty new to the Zend Framework and having no luck with the error controller either. I have a slightly different setup to the others, but nothing drastic. I have 3 'modules' defined - public (default), shared, and admin. Public uses the preDispatch method of the Zend_Controller_Plugin_Abstract:
[PHP]<?php
# Route all requests to the index controller / index action
class APP_Controller_Plugin_CleanUrls extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
if($request->module == 'public')
{
# This is the dynamic part of the site - route everything to the index controller
$request->setControllerName('index');
$request->setActionName('index');
}
else
{
echo 'using: '.$request->module.' module<br />';
}
}
}[/PHP]
and for now lets me know which module I am using if it is not the default (public) one. The index controller works as planned handling 404s / 500s etc itself without the error controller. However, I do want this enabled for the admin part of the site. The important part of my bootstrap file is as follows:
[PHP]# Get the front controller
$frontController = Zend_Controller_Front::getInstance();
$frontController->setControllerDirectory(array(
'public' => APP_DIR.'core'.DS.'public'.DS.'controllers',
'shared' => APP_DIR.'core'.DS.'shared'.DS.'controllers',
'admin' => APP_DIR.'core'.DS.'admin'.DS.'controllers'
));
$frontController->setDefaultModule('public');
$frontController->registerPlugin(new APP_Controller_Plugin_CleanUrls());[/PHP]
My admin IndexController file works fine, as does the admin ErrorController file if I reference it absolutely: http://local.zendTest/admin/error/error. However, if I try http://local.zendTest/admin/error/errorX or http://local.zendTest/admin/X I get the following:
[HTML]using: admin module
using: admin module
using: admin module
Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (error)'
in C:\Server\htdocs\cms\framework\Zend\Controller\Dis patcher\Standard.php:249
Stack trace:
#0 C:\Server\htdocs\cms\framework\Zend\Controller\Fro nt.php(914):
Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#1 C:\Server\htdocs\cms\sites\site1\public\index.php( 9):
Zend_Controller_Front->dispatch()
#2 {main} thrown in C:\Server\htdocs\cms\framework\Zend\Controller\Dis patcher\Standard.php on line 249[/HTML]
Not sure what I am doing wrong? My admin ErrorController looks like this (pretty much straight out of the manual) where APP_Controller_Action is my own override:
[PHP]<?php
class Admin_ErrorController extends APP_Controller_Action
{
public function errorAction()
{
$errors = $this->_getParam('error_handler');
if(is_object($errors))
{
switch($errors->type)
{
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()->setHttpResponseCode(404);
$this->view->message = 'Page not found';
break;
default:
# application error
$this->getResponse()->setHttpResponseCode(500);
$this->view->message = 'Application error';
break;
}
$this->view->title = 'Errors';
$this->view->env = $this->getInvokeArg('env');
$this->view->exception = $errors->exception;
$this->view->request = $errors->request;
}
else
{
$this->view->title = 'No Errors';
$this->view->message = 'No Errors Detected';
}
}
}[/PHP]
Can anyone shed any light on this situation at all?
Thanks in advance,
Paul
Found a work around online (credit to Daniel Cousineau). Apparently the ZF does not allow for multiple error controllers by default - God knows why not - it is very useful to be able to handle errors differently for different modules...
[PHP]<?php
class APP_Controller_Plugin_ErrorControllerSelector extends Zend_Controller_Plugin_Abstract
{
public function routeShutdown(Zend_Controller_Request_Abstract $request)
{
$front = Zend_Controller_Front::getInstance();
# If the ErrorHandler plugin is not registered, bail out
if(!($front->getPlugin('Zend_Controller_Plugin_ErrorHandler' ) instanceOf Zend_Controller_Plugin_ErrorHandler))
{
return;
}
$error = $front->getPlugin('Zend_Controller_Plugin_ErrorHandler' );
# Generate a test request to use to determine if the error controller in our module exists
$testRequest = new Zend_Controller_Request_HTTP();
$testRequest->setModuleName($request->getModuleName())
->setControllerName($error->getErrorHandlerController())
->setActionName($error->getErrorHandlerAction());
# Does the controller even exist?
if($front->getDispatcher()->isDispatchable($testRequest))
{
$error->setErrorHandlerModule($request->getModuleName());
}
}
} [/PHP]
and then in the bootstrap just register an extra plugin:
[PHP]<?php
$frontController->registerPlugin(new APP_Controller_Plugin_ErrorControllerSelector());
?> [/PHP]
Hope this helps someone else!
Brand new to Zend, but the above post is the answer. Luckily I actually wanted a single error handler for all of my modules, at least to start out with.
All I needed in my bootstrap was:
Whereby I have an 'error' module, with an ErrorController.php in the controllers directory which defines the Error_ErrorController class with an errorAction() method in it.Code:$front->registerPlugin(new Zend_Controller_Plugin_ErrorHandler(array( 'module' => 'error', 'controller' => 'error', 'action' => 'error' )));
Works like a clock. Catches missing modules, missing controllers across different modules, etc.