Recent Posts
- (10/14) Forcing A Single Join in CakePHP PaginationTAGS:CakephpCakephp 13DatabaseErrorsHabtmMysqlMssqlWeb ProgrammingUsage
- (08/11) Inserting NOW() into MySQL Using CakePHPTAGS:CakephpDatabaseMysqlMssqlWeb ProgrammingUsage
- (08/07) Best PaginateCount for CakePHP - with Group By SupportTAGS:CakephpBehaviorsWeb ProgrammingUsageDatabaseExampleMysqlHabtmHack
- (04/03) CakePHP Error Messages Not Showing on FormTAGS:CakephpCakephp 13Web ProgrammingErrorsUsage
- (02/06) Sorting Paginated Results Using a Related Model Field in CakePHPTAGS:CakephpWeb ProgrammingUsageExample
- (11/02) Changing CakePHP's Model useTable on the FlyTAGS:CakephpWeb ProgrammingMysqlDatabaseExampleTutorial
- (10/18) The Funniest Error Message Ever - Thank You EclipseTAGS:EclipseWeb ProgrammingErrorsHumorWindowsUsageSoftwarePhpCakephp
- (09/27) Upgrading CakePHP Application to 1.3 (from 1.2)TAGS:CakephpUpgrade
Subscribe to my feed
MainelyDesign.com Blog
Controlling CakePHP Error Handling When Debug = 0
Posted on 04/19/2010 at 04:27 pm by Kevin Wentworth
Viewed 8,527 times | 3 comments
I finally had a client request a piece of functionality that required me to program CakePHP so I could better control the default error handling when the site is in production mode (i.e. debug is set to 0). By default, CakePHP will throw a 404 page not found header whenever ANY errors occur on a production site with debug equal to zero. This works great, most of the time. But what about when you are having database connectivity issues? Say when there are too many mysql connections to that overloaded shared hosting box? Modifed CakePHP error handling to the rescue.
Override Default AppError Functionality
By default, when your website has a debug level of 0, CakePHP will automatically use AppError::error404() to communicate error messages. This is done to prevent any sensitive data being released through error messages. However, if you want to actually use error methods other than error404() on a production site, you must do a little trick, I picked up:
- function __construct($method, $messages) {
- Configure::write('debug', 1);
- parent::__construct($method, $messages);
- }
This basically makes your site work as if Configure::write('debug', 0); but sets the erorr class to have a debug of 1, so different messages can be used and not just the 404 error message function.
Hijack CakePHP's Default Error Handling
The next step is hijacking all the CakePHP error methods that you need and make them do what you want. For me, this was the missing table and missing database errors. But, I also wanted to check the 404 error and make sure there wasn't database connectivity issues (My 404 page requires a database lookup, so it wouldn't work if there wasn't any DB connection). I decided to make a few functions that would simplify the code:
Checking for DB Connectivity: (Thanks to Miles)
- function _testDBConnectivity() {
- Configure::write('debug', 0); //hide messages in case DB isn't available
- $this->DB = ConnectionManager::getDataSource('db_connection_name');
- if(!$this->DB->isConnected()) {
- return false;
- } else {
- return true;
- }
- }
Hooking into missingTable() and missingDatabase():
Notice the _genericErrorMessage(); calls in the first line of each function.
- function missingTable($params) {
- $this->_genericErrorMessage(); //won't return unless debug is > 0
- 'model' => $className,
- 'table' => $table,
- 'title' => __('Missing Database Table', true)
- ));
- $this->_outputMessage('missingTable');
- }
- $this->_genericErrorMessage(); //won't return unless debug is > 0
- 'title' => __('Scaffold Missing Database Connection', true)
- ));
- $this->_outputMessage('missingScaffolddb');
- }
Hooking into error404() (needed to force the message, b/c I know an error has happened):
If DB fails, show the genericErrorMessage() and force it to show, even if debug isn't 0
- function error404($params) {
- if(!$this->_testDBConnectivity()) {
- $this->_genericErrorMessage(true); //won't return unless debug is > 0
- }
- $url = $this->controller->here;
- }
- $url = Router::normalize($url);
- 'code' => '404',
- 'name' => __('Not Found', true),
- 'message' => h($url),
- 'base' => $this->controller->base
- ));
- $this->__outputMessage('error404');
- }
Function to output customized error message when database connectivity goes down:
- //checks public debug level setting and "hijacks" errors if public debug level is set to 0
- //....and no DB connection, otherwise cakephp's error message show (for development)
- function _genericErrorMessage($override = false) {
- $publicDebugLevel = Configure::read('public.debugLevel');
- if($publicDebugLevel == 0 or $override) {
- Configure::write('debug', 0); //eliminate all future warnings
- $this->controller->layout = Configure::read('siteLayout'); //set layout
- $this->controller->theme = Configure::read('siteTheme'); //set theme
- $this->_outputMessage('genericError'); //output generic error message
- }
- }
Keeping the Search Engines in Mind
I'm sending a 500 error along with the customized error message, because I want search engines to know there was an issue with the site, not a 404 page missing error. Hopefully, this will help eliminate the risk of search engines thinking the page is gone for good.
Wrapping Up CakPHP Error Handling Overrides
What I like most about this approach is the ability to still use the CakePHP error handling when your site isn't in production mode. And, when it's in production mode it will show a 404 error message unless it's a database error. One difference between my setup and the default CakePHP setup, is that I have an additional configuration variable that I use for setting the debug level (it's part of CMS logic). You cannot use just CakePHP's debug setting, because it will be set to 1 by the __constructor() function of the AppError class.
Cheers,
-Kevin
Tags for Controlling CakePHP Error Handling When Debug = 0
Cakephp | Web Programming | Seo | Php | Mysql | Database | Example | Tutorial
Comments for this Posting
Posted by Fruitraxinito
on 2/3/11
Fear rules almost every newsroom in the country.
Posted by Nogduedogar
on 3/3/11
When I got there, all the pasta and science stuff hadn't quite caught on in England - things that were perfectly acceptable then wouldn't be tolerated now.

Posted by chad
on 15/9/10
I updated the error404() in my AppError class to start with:
// When CakePHP's 'debug' is set to 0 for production mode the
// Cake library ignores the method name you passed to the
// cakeError() function. Instead it calls this error404()
// function.
//
// To be able to call our own error views in production mode
// we pass the error name in using the $params argument and
// then here we check for that parameter name and call the
// correct method.
//
// Example: to call the soapLookupFailed() method call
// cakeError() via:
//
// $error_params = array('error_method' => 'soapLookupFailed');
// $this->cakeError('soapLookupFailed', $error_params);
if(array_key_exists('error_method', $params)) {
call_user_func(array($this, $params['error_method']), $params);
return;
}