How to customize error handling in console-mode applications

One can control the detail of a web application in the webroot/index.php file by manipulating the values of YII_DEBUG and YII_TRACE_LEVEL, but these don't appear to be used by console applications. This is because although the base CApplication class defines a displayError() method that does consider these variable, CConsoleApplication overrides it with a function that doesn't honor them.

This means that console app errors produce huge stacktraces that scroll right by.

This can be easily fixed by setting up a wrapper class to CConsoleApplication that overrides this error handling, and then using this class when instantiating the app.

1) Create a wrapper class for the CConsoleApplication system class:

// in protected/components/MyConsoleApplication.php

class MyConsoleApplication extends CConsoleApplication {

    public function displayError($code, $message, $file, $line)
        echo "PHP Error[$code]: $message\n";
        echo "in file $file at line $line\n";

        if (YII_DEBUG) debug_print_backtrace();

This function was taken directly from CConsoleApplication::displayError, but we've added the conditional test for YII_DEBUG. You can of course customize it in any other way you like, as well as override any other features of CConsoleApplication.

2) Update your console entry script to reflect the new wrapper class.

Normally we use the Yii::createConsoleApplication() method, but all that really does is call new on the class, so we can replace it with our own call. And since Yii isn't quite running yet the autoloader is not in place, so we have to explicitly require_once the wrapper.

I normally put my console wrappers in the protected/exec/ folder because other scripts are found there too. The console entry script now looks like:

# Script found in protected/exec/myconsole.php


$protected = dirname(__FILE__) . '/..';
$yii       = "$protected/../yii/framework/yii.php";   // EDIT THIS TO TASTE
$config    = "$protected/config/console.php";

define('YII_DEBUG', false);

require_once( $yii );
require_once( "$protected/components/MyConsoleApplication.php" );

// Yii::createConsoleApplication($config)->run();    // DELETE THIS
$app = new MyConsoleApplication($config);            // ADD THIS

With this change made, errors from console apps produced detailed backtraces or not depending on how you define YII_DEBUG.