Reputation: 53881
Context:
I have three environments for an app: dev (local), test/staging (prod server), production. The app knows which is which. Error reporting on both staging and production is 0, so errors are never shown. On dev I want to see errors immediately and I want to see them where they happen, so not in some log, but in the code's result.
However, I don't want to see the errors I have explicitly suppressed with @
. I've been using fsockopen
and that throws a warning when it can't connect. I accept the no-connection, but don't want to see the error. Not even on dev.
Apparantly all errors go though the custom error handler, even if they were suppressed in the code.
My error handler has only 4 arguments: errno, error, file, line. From those I can't see whether the error was originally suppressed or not. If I can see that there, I can choose whether to print the error (right now I always do, if env=dev).
Any ideas? Or maybe on how to completely ignore suppressed errors (so that they don't even reach the custom error handler)?
Upvotes: 12
Views: 2415
Reputation: 31
Add this too your handler
// error was suppressed with the @-operator
if (0 === error_reporting()) { return false;}
Upvotes: 0
Reputation: 2110
So in PHP 8.0, you can no longer tell if the error/warning/notice, etc, was suppressed (using @) simply by checking if error_reporting() == 0.
Instead, it is now a fairly long piece of bitwise operators with constants, described in a warning box here: https://www.php.net/manual/en/language.operators.errorcontrol.php
In your custom error handler, if you want to tell if your error was suppressed with the @ sign, use something like this:
$PHP_8_SUPPRESSED = E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE;
$er = error_reporting();
if ($er === 0 || $er === $PHP_8_SUPPRESSED) {
// do code because it was suppressed. Ex: return FALSE, etc.
}
At the time of this writing, $PHP_8_SUPPRESSED
will equal integer value 4437
, but it's probably best not to hard-code that, since future versions of PHP might change these constant values.
Quick side note: I really wish they had just created a new constant called "E_SUPPRESSED_ERROR" or something like that we could check. But sadly they did not!
Upvotes: 8
Reputation: 53950
error_reporting
@
. In a rare case you want to ignore an error, use an empty catch blockUpvotes: 1
Reputation: 28793
There's a hint to this in the set_error_handler
manual page.
[the
error_reporting()
] value will be 0 if the statement that caused the error was prepended by the @ error-control operator
When you use the error control operator @
, what is happening is this:
error_reporting(0)
The slightly confusing quote above refers to the fact that error_reporting
returns the current setting. If you have suppressed the error with the control operator, calling error_reporting()
will return 0.
Therefore, if you know you have set it to non-zero (ie you are reporting some errors) and it returns zero, you know the error was suppressed.
If you detect a suppressed error and want to know what it was, you can find it in the variable $php_errormsg
(if track_errors
is set to true
in php.ini
).
Note that the error control operator causes a lot of overhead, as it changes the error reporting level twice each time it is used. It will slow down your script.
Upvotes: 22