User tests: Successful: Unsuccessful:
It's a somewhat common and accepted practice in the PHP ecosystem for libraries to use PHP's trigger_error()
function to raise deprecation notices (the Symfony ecosystem being the most prevalent example of this). So, let's implement an error handler that can process these and use it in core (FWIW this would allow us in the Framework to start using this practice without spamming CMS installs with error messages).
Apply the patch and make sure the debug plugin is logging deprecated errors. Pre- and post-patch the deprecations in Joomla\CMS\Factory
should continue to be logged.
Category | ⇒ | Libraries |
Status | New | ⇒ | Pending |
The first Symfony release that had the trigger_error()
support didn't use suppression and it caused issues for downstream folks (I forget what specifically, you'll have to go back through their issues to find the specifics, I just remember it was Symfony 2.7 that introduced it and 2.7.1 added suppression).
Isn't it better to allow sites to use their own error handling plugins? Forced logging of all exceptions (started from Joomla 3.5?) or deprecations will duplicate custom error handlers job and spam main log.
Example:
public static function onError ($errGroup, $message, $file, $line) {
$errGroup &= error_reporting();
// If error should be handled in according to error_reporting settings
if ($errGroup) {
// Detect problematic extensions, which should be ignored
$app = \JFactory::getApplication();
$isIgnoredExtension = false;
if (!$isIgnoredExtension) {
$e = new \ErrorException($message, 0, $errGroup, $file, $line);
$file = Dumper::relPath(Path::local()->normalize($file), static::$appRoot);
$line = $line ?: '??';
$dumper = Dumper::getInstance(['appRoot' => static::$appRoot]);
$callStack = $dumper->dumpTrace($e->getTrace());
$errName = isset(static::$kPhpErrorNames[$errGroup]) ? static::$kPhpErrorNames[$errGroup] : "#$errGroup";
$message = "PHP Error $errName in $file ($line): $message\r\n\r\nCallstack:\r\n\r\n$callStack";
JLog::add($message, JLog::ERROR, 'phperror');
$message = null;
} // .if
} // .if
} // .function onError
Not all users check the main system log (or for that matter the Joomla log, but ¯\_(ツ)_/¯
). So attempting to log things through Joomla's API is a last ditch effort to make sure errors get recorded in some way that can be tracked.
Moving "core" error handling functionality into plugins probably shouldn't happen. It's a good idea to expand the system to support events, but it also needs to be able to work if the error happens so early the event system (and plugins) can't be used at all. How far do we really want to take that though, do we really want a handler registered through set_error_handler()
that lets plugins handle all possible PHP related errors (at least the ones that can be handled through that function)? IMO, it's better for plugins to set up a handler through our onAfterInitialise
event to add custom functionality, and if we add event support I would leave that specifically for handling uncaught Throwables and dispatch something similar to Symfony's ConsoleEvents::ERROR
or KernelEvents::EXCEPTION
events.
I see. Your variant is better, than writing directly to log, as it was before. Projects will still be able to install their own exception/error/fatal error handlers in onAfterInitialise event of system plugins and handle necessary messages.
The only remaining problem is that ExceptionHandler (or JErrorPage) logs HTTP exceptions. For now, when you want to signal, that page is not found in any extension, you throw exception, passing HTTP response code as exception code. And of course, you don't want to log all those 403, 500, 404, etc. exceptions. Especially it's true for projects with their own exception/error/fatal error handlers. Is it normal, that the same method is responsible for errors logging and error page rendering? Currently to deal with this issue (lots of 404 exceptions in logs) I had to patch JErrorPage and cut all those JLog::add programatically (((
The ExceptionHandler class is the global uncaught Exception handler. So any uncaught Exception (by design or someone failing to implement proper error handling) eventually bubbles up to it.
If we can get to an event driven system, that log statement might be something worth moving to something like the debug or log plugins. Otherwise, it'd be pretty difficult to put something in the UI right now (or even some kind of PHP only API) to try and control what types of errors get logged by that method.
Status | Pending | ⇒ | Fixed in Code Base |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2017-09-17 12:54:12 |
Closed_By | ⇒ | wilsonge | |
Labels |
Added:
?
|
Why the at sign before the trigger_error calls?