Hide PHP errors in ExpressionEngine - php

I recently switched hosts with a new PHP version. I'm getting an error from a plugin (Calendar) that just won't go away. It's a non-static method error that is causing 0 issues and it can't be fixed without trying a different plugin. I'm at the point where I just need it gone so this ugly message isn't showing on every page and I'll debug it later. I have tried disabling errors, setting every debug setting I can find to 0, but this error message won't go away! It's showing to everyone. What setting am I missing???
I've set the index.php debug=0
I've set the config.php $config['debug'] = 0;
I've added in an extra ini_set for display_errors and error_reporting to 0
I've double checked that the settings in the config file editor and output and debugging pages are showing 0
Why aren't any of these settings working? I'm using EE 2.5.5

What you are looking for is error suppression, you can find more info on it here
Code example
class foo {
public function bar() {
echo 1;
}
}
foo::bar(); // Strict standards: Non-static method foo::bar() should not be called statically
#foo::bar(); // no warning
The # symbol will suppress any error resulting in the fopen.

Related

Log only real fatal errors from PHP-FPM in Docker container

I'm using NGINX with PHP-FPM in seperated Docker containers. I want to get errors only to stderr, so that I can collect them on a centralized log-server. Problem is: I'm using WP and seems to have some not well written plugins. They work but cause warnings like this:
2017/06/17 01:16:08 [error] 7#7: *1 FastCGI sent in stderr: "PHP
message: PHP Warning: Parameter 1 to wp_default_scripts() expected to
be a reference, value given in /www/wp-includes/plugin.php on line 601
Example script for testing, which should give me a fatal error in the stderr:
<?php
not_existing_func();
PHP-FPM was configured to log errors to stderr like this:
[global]
log_level = error
error_log = /proc/self/fd/2
I'm wondering that this gave me nothing in the script above. Just after I switched the log_level to at least notice, I got the exception on the console of the docker container:
[17-Jun-2017 01:45:35] WARNING: [pool www] child 8 said into stderr:
"NOTICE: PHP message: PHP Fatal error: Uncaught Error: Call to
undefined function not_existing_func() in /www/x.php:2"
Why the hell is this a notice? For me we've clearly a fatal error here like the message indicates, cause the script can't continue (and we get a 500 error in the browser, of course). It can't be true that I have to set log_level to notice so that I don't miss fatal errors which are delcared as warnings. And simultaneously, my logs get filled with trash warnings from wordpress themes, plugins and so on, that I haven't developed and I don't want to fix for update reasons...
I tried a bit and found out that log_errors in php.ini is essential for PHP-FPM to get any information. But the log level from error_reporting seems wired too. For testing purpose, I used the following configuration:
display_errors = Off
log_errors = On
error_log = /proc/self/fd/2
;error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR
error_reporting = 0
Result: I got notices, but NO info about my fatal error...
First of all, I learned that I was wrong: Wordpress is the root cause for this issue, not PHP directly. It's a known fact that WP manipulates the error_reporting when debugging is enabled, so I tried to define WP_DEBUG as false in my config; BUT even having this set, the documentation says
[...]
Except for 'error_reporting', WordPress will set this to 4983 if WP_DEBUG is defined as false.
[...]
So my settings into php.ini were correct and sufficient. I don't even need the php-fpm settings, when errors are redirected to stdout in the php.ini file.
How to prevent WordPress from manipulating the error reporting?
This is not so easy, too. Although the WordPress documentation says, that the wp-config.php is a good place to set global wide settings like the error reporting, they got overwritten later to 4983. I don't know where; maybe it's not even the Core of Wordpress, but rather some poor developed plugin or theme.
We can handle this by adding error_reporting to the disabled functions:
disable_functions = error_reporting
Now it's not possible to overwrite our error_reporting. I think this is the best solution to make sure that we don't get any other error reporting by external influence from plugins or themes. Also in the future, since PHP allows such chaos, we need to reckon with such things.
Basically, we could criticize that this prevent us from getting more logs by setting WP_DEBUG to true, that's right, but as we're on a production system, it seems wrong for me to do troubleshooting in such a way there. We shouldn't do this on an application base, especially without display_errors! Instead, the workflow to find problems should be to look at the error logs.
Fatal errors should always be logged and checked on a regular basis. If that is not enough, error_reporting could be set on a higher level to get information about possible problems like warnings.

Why didn't a missing class file throw a PHP error?

Sorted out this issue. Problem was the class file (and the folder, actually) was missing. Puzzled why with display_errors = On and E_ALL | E_STRICT defined (and Apache restarted), this would throw a white screen of death and not an error.
phpinfo() shows that the master value and the local value are the same, so I'm assuming that the error settings are not being overwritten somewhere in the code base (in an .htaccess or ini_set() call).
EDIT
The new object instantiation is here:
$type['content_object'] = new $type['handler_class']();
I also tried instantiating it without the variable, i.e. new Foo(); but still gave WSOD.
There might be an alternative error handler activated. Call restore_error_handler() prior to the line with the error (possibly multiple times) to reactivate PHP's default error handler.

E_STRICT messages thrown though not set

Since updating my testing server to PHP 5.3.3 (Debian Squeeze) I encountered strange behaviour regarding the error reporting in PHP.
I set error_reporting like this:
error_reporting(E_ALL);
and checked the setting via
echo error_reporting();
which echoes 30719. According to php.net this means "All errors and warnings, as supported, except of level E_STRICT.".
But in the very next line (a class definition abstract class formInputContainer extends formContainer implements formElementValueable { ... }) this results in the message:
Strict (2048): Declaration of formInputContainer::addElement() should be compatible with that of formContainer::addElement()
Why is the E_STRICT message echoed though it's not set? Even changing to E_ALL & ~E_STRICT does not help.
The reason you're seeing them even though they are not set, is that these are thrown at compile time (well, parse time). That means the errors are triggered before your error_reporting() call is made. The real fix is to change the php.ini setting to remove E_STRICT from the definition. To make sure you're editing the correct file, check phpinfo().
If this is a custom error handler (set via set_error_handler()), you'll have to check the current error_reporting level by yourself. A custom error handler gets all error messages:
The manual says:
It is important to remember that the standard PHP error handler is completely bypassed for the error types specified by error_types unless the callback function returns FALSE. error_reporting() settings will have no effect and your error handler will be called regardless - however you are still able to read the current value of error_reporting and act appropriately.

Magento whitescreening when data model load called

I've set up my config.xml and my controller, my data model class and resource class and I can see that the classes are loading and can echo out the object and NULL data object information.
However, when I try to call the ->load method of the data model object, I get the whitescreen of death. I've double checked and triple checked my config.xml and I'm not sure what I'm doing wrong or what to look for next...can anyone help?
Thanks!
Kristina
PHP never errors out without telling you why, it's just a matter of finding the right log.
First, check your Magento exception log
var/log/exception.log
Second, check your PHP Error log. If you're not sure where the that, run phpinfo() from a blank file on your server and look for the
error_log
variable. If this isn't set, set it via the ini_set function, or by changing your php.ini file.
If you leave error_log unset, PHP will send logs to the "SAPI error logger", which is a fancy way of saying your apache error log.
Finally, although it won't help with all white screen cases, try turning developer mode on. There's the following line in index.php
if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])) {
Mage::setIsDeveloperMode(true);
}
So either set MAGE_IS_DEVELOPER_MODE in your .htaccess file, or just comment out the conditional. This will turn off the default error reporting and output exceptions/errors/warnings/etc to the browser.

Detecting error-control operator

Please tell me if this is correct. In my error handler, I need to be able to detect when the # error-control operator was used to suppress errors, because some external libraries (sadly) use it a lot. Execution of the script should continue, just like when you don't use custom error handlers.
When the at-sign is used, PHP temporarily sets error_reporting to 0. So at the start of a script we set error_reporting to any value but zero - we can now do some beautiful IF/ELSE magic. To avoid any errors being shown at the frontend, we also set display_errors to 0, this will override error_reporting (but we can still use it's value for magic).
<?php
ini_set('display_errors',0);
error_reporting(E_ALL);
function error_handler($errno, $errstr, $errfile, $errline)
{
if (error_reporting()===0) return;
else die();
}
set_error_handler('error_handler');
//This issues an error, but the handler will return and execution continues.
//Remove the at-sign and the script will die()
#file();
echo 'Execution continued, hooray.';
?>
So.. Are there no catches here? Except the one where the external library overrides my error handling.. (any tips on that?)
Considering what your script does, and some user notes on the # operator manual page, it seems what you are doing is OK.
For instance, taras says :
I was confused as to what the # symbol
actually does, and after a few
experiments have concluded the
following:
the error handler that is set gets called regardless of what level the
error reporting is set on, or whether
the statement is preceeded with #
it is up to the error handler to impart some meaning on the different
error levels. You could make your
custom error handler echo all errors,
even if error reporting is set to
NONE.
so what does the # operator do? It temporarily sets the error reporting
level to 0 for that line. If that line
triggers an error, the error handler
will still be called, but it will be
called with an error level of 0
And the set_error_handler manual page seems to confirm that :
Of particular note is that this value will be 0 if the statement
that caused the error was prepended by the # error-control operator.
Here too, there are some user notes that can be useful ; for instance, this one (see the begining of the code)
Still, if what you want is to "disable" the effect of the # operator (not sure I understood the question correctly ; this might help you anyway), to be able to get the error messages while you are on your development environment, you can install the scream extension (pecl, manual)
Provided you configure it the right way, setting this in your php.ini (after installating/loading the extension, of course) :
scream.enabled = 1
This extension will simply disable the # operator.
And here's an example (quoting the manual) :
<?php
// Make sure errors will be shown
ini_set('display_errors', true);
error_reporting(E_ALL);
// Disable scream - this is the default and produce an error
ini_set('scream.enabled', false);
echo "Opening http://example.com/not-existing-file\n";
#fopen('http://example.com/not-existing-file', 'r');
// Now enable scream and try again
ini_set('scream.enabled', true);
echo "Opening http://example.com/not-existing-file\n";
#fopen('http://example.com/another-not-existing-file', 'r');
?>
And this will output :
Opening http://example.com/not-existing-file
Opening http://example.com/not-existing-file
Warning: fopen(http://example.com/another-not-existing-file): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in example.php on line 14
I am not sure I would use this extension on a production server (where I never want errors displayed), but it is very useful on a development machine, when using old code, on an application/library that uses # operator extensivly...

Categories