Here’s the problem: I want to develop in debug mode (i.e. WP_DEBUG set to “true”) to catch all the notices, warnings, and strict standard errors in my theme and plugin code, but several of the third party plugins that I have activated are also puking errors all over the place. I’ve already reported these errors to the developers (and maybe even submitted a pull request) and I’m sure they’ll get fixed eventually, but how do I continue working in debug mode in the meantime?
I could rely on the Debug Bar and Log Deprecated Notices plugins to catch the errors. I’ve tried this, but unfortunately I’ve found that it misses reporting some errors and I don’t know about them until I receive a bug report. Also, Debug Bar currently does not support capturing Strict Standards (PHP 5.4+) errors.
If an offending plugin isn’t required for the site to work, I could just deactivate it. This is not a great solution though because there could be a bug with how the plugin interacts with my code and by deactivating the plugin, we’re not testing any of that during development.
I could turn debug mode off and then just turn it on now and then to check if there are any errors showing up. This is a horrible solution though as I may miss out on catching some errors during development.
Sadly, the former two solutions is what I had been doing. I recently decided that it was no longer acceptable and set out to find a better way.
I now set WP_DEBUG_DISPLAY to false and WP_DEBUG_LOG to true in my wp-config.php for my local dev environment. This stops errors from showing in the browser and instead prints them to a log file at wp-content/debug.log. The advantage here is that we can still inspect the errors by looking at that log file and they aren’t being puked all over the UI, so we can still navigate the site and test it.
Closing and reopening this log file to get the latest entries is tedious, so I open the command line, and run tail -f wp-content/debug.log
. The -f
will keep the tail command running and when anything is added to debug.log, it will be output to the terminal automatically. So as errors occur, they will instantly show in our terminal. To stop the command from running, simply press Ctrl-C.
This is pretty good, but we’re not much further ahead than before. We still have all these errors from the 3rd-party plugins polluting the the log file:
[02-Mar-2014 15:22:20 UTC] PHP Strict Standards: Declaration of Social_Service_Facebook_Account::child_account_avatar() should be compatible with Social_Service_Account::child_account_avatar() in /wp-content/plugins/social/lib/social/service/facebook/account.php on line 6 [02-Mar-2014 15:22:20 UTC] PHP Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method AKTT::admin_controller() should not be called statically in /wp-includes/plugin.php on line 429 [02-Mar-2014 15:22:21 UTC] PHP Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method AKTT::admin_menu() should not be called statically in /wp-includes/plugin.php on line 429 [02-Mar-2014 15:22:21 UTC] PHP Strict Standards: Declaration of Social_Service_Facebook_Account::child_account_avatar() should be compatible with Social_Service_Account::child_account_avatar() in /wp-content/plugins/social/lib/social/service/facebook/account.php on line 6 [02-Mar-2014 15:22:21 UTC] PHP Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method AKTT::admin_controller() should not be called statically in /wp-includes/plugin.php on line 429 [02-Mar-2014 15:22:21 UTC] PHP Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method AKTT::admin_enqueue_scripts() should not be called statically in /wp-includes/plugin.php on line 429
As you can see, if there was an actual error in my code, it would be very hard to spot it amongst all these third party plugin errors. But not to worry, regular expressions to the rescue again! We can pipe the output through grep to filter out the unwanted errors.
tail -f wp-content/debug.log | grep -v -E "(/wp-content/plugins/twitter-tools|social/)|AKTT::"
The -v option tells grep to exclude any matches. The -E option enables enhanced regular expressions, so we can use things like a pipe character for OR.
Our pattern should match any errors in files in /wp-content/plugins/twitter-tools/ or in /wp-content/plugins/social/. There were also some strict standards errors caused by the Twitter Tools plugin but reported as file /wp-includes/plugin.php. I don’t want to exclude any errors reported by that file as they could be errors from my code as well. Instead, I also exclude any errors containing the string “AKTT::”.
I can continue adding more strings and file paths as I encounter more errors from 3rd-party plugins that I want to filter out.
One thing to note here is that this filtering doesn’t work if you have Xdebug enabled. Our grep filtering assumes that each error only prints one line to the debug.log but Xdebug actually prints a stack trace over many lines:
[02-Mar-2014 17:50:44 UTC] PHP Strict standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method AKTT::import_tweets() should not be called statically in /wp-includes/plugin.php on line 429 [02-Mar-2014 17:50:44 UTC] PHP Stack trace: [02-Mar-2014 17:50:44 UTC] PHP 1. {main}() /wp-cron.php:0 [02-Mar-2014 17:50:44 UTC] PHP 2. do_action_ref_array() /wp-cron.php:100 [02-Mar-2014 17:50:44 UTC] PHP 3. call_user_func_array() /wp-includes/plugin.php:507 [02-Mar-2014 17:50:44 UTC] PHP 4. Social->cron_15_init() /wp-includes/plugin.php:507 [02-Mar-2014 17:50:44 UTC] PHP 5. Social_Request->execute() /wp-content/plugins/social/social.php:1211 [02-Mar-2014 17:50:44 UTC] PHP 6. Social_Controller_CRON->action_cron_15() /wp-content/plugins/social/lib/social/request.php:191 [02-Mar-2014 17:50:44 UTC] PHP 7. do_action() /wp-content/plugins/social/lib/social/controller/cron.php:44 [02-Mar-2014 17:50:44 UTC] PHP 8. call_user_func_array() /wp-includes/plugin.php:429
And so our grep solution will only filter out the first line and still output the entire stack trace. I’ve simply disabled Xdebug as I very rarely need the stack trace, but you could certainly write a script that filters out the appropriate stack traces and drop it in as a replacement for the grep command:
tail -f wp-content/debug.log | filter-errors
Maybe you already have a script to share with us? Or maybe you have a better solution? Please share in the comments.