Let’s assume we do not want to show any errors when a non-existing controller is called. The user should simply be redirected to the homepage in such a situation. To accomplish that we have to write a custom error handler.

First, we have to create a file called “error.php” in the “app” directory. We add an “AppError” class to this file which extends the default error handler (cake/libs/error.php) and override the “missingController” function.

class AppError extends ErrorHandler
{
    function missingController($params)
    {
        $this->controller->redirect('/');
    }
}

That’s it? Unfortunately, no. This solution works when we use a debug level > 0, but with a debug level of 0 we get a 404 error. We find the reason for that behaviour in the following lines of the default error handler’s constructor:

if (DEBUG > 0 || $method == 'error') {
    call_user_func_array(array(&$this, $method), $messages);
} else {
    call_user_func_array(array(&$this, 'error404'), $messages);
}

So we have to write our own constructor in our class (fortunately, we can copy almost the entire constructor of the default error handler). Now our AppError class looks like:

class AppError extends ErrorHandler
{
    function __construct($method, $messages)
    {
        static $__previousError = null;
        $this->__dispatch =& new Dispatcher();

        if ($__previousError != array($method, $messages))
	{
            $__previousError = array($method, $messages);

            if (!class_exists('AppController'))
            {
                loadController(null);
            }

            $this->controller =& new AppController();
            $this->__dispatch->start($this->controller);

            if (method_exists($this->controller, 'apperror'))
            {
                return $this->controller->appError($method, $messages);
            }
        }
        else
        {
            $this->controller =& new Controller();
        }

        call_user_func_array(array(&$this, $method), $messages);
    }

    function missingController($params)
    {
        $this->controller->redirect('/');
    }
}

Thanks to PhpNut for the hint with the constructor, and to drSwank for asking in the irc.