Bug #77205 [Nab]: No E_ERROR level output from a recursive autoloading call
| From: | claudio dot luis at aptoide dot com | Date: | Mon, 26 Nov 2018 19:21:27 +0000 |
| Subject: | Bug #77205 [Nab]: No E_ERROR level output from a recursive autoloading call | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-218144@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=77205&edit=1
ID: 77205
User updated by: claudio dot luis at aptoide dot com
Reported by: claudio dot luis at aptoide dot com
Summary: No E_ERROR level output from a recursive autoloading
call
Status: Not a bug
Type: Bug
Package: SPL related
Operating System: Linux (Ubuntu)
PHP Version: 7.2.12
Block user comment: N
Private report: N
New Comment:
I agree with the above.
The use-case that spawned this was an autoloader I did a while ago which has this "@"
before the include, because it's expected to fail and it always outputs/logs a warning whenever
so (and it's the only case where I used "@").
Although looking at it again, I could just use stream_resolve_include_path to check for the path
first and do an include without this suppression in the first place, making my code completely
@-free (which I just did).
Having that said, with "@" suppressing even E_ERROR level errors, the program will just
halt silently with no further output, and I am not seeing the use case where such a behavior would
be useful (that's one of the reasons why I tend to avoid "@").
Previous Comments:
------------------------------------------------------------------------
[2018-11-26 19:00:32] spam2 at rhsoft dot net
> I think we should exclude errors above the warning level from error suppression
yes!
a Fatal Error or Exception you don't see leading to a white page and empty error logs is not
that helpful, especially when it comes to deprecation warnings you don't see and after the next
php update they ead to a white page - been there with 5.4
------------------------------------------------------------------------
[2018-11-26 18:49:03] nikic@php.net
Side note, I think we should exclude errors above the warning level from error suppression. @ is
usually used to suppress expected warnings, but if something more severe happens in between,
that's a hard to debug WSOD.
------------------------------------------------------------------------
[2018-11-26 18:43:28] claudio dot luis at aptoide dot com
No, that's not what I intended to report, but now that you mention it, I believe you pretty
much nailed it, and the error is on my side, silly me. :)
Essentially, the first include (class A) triggers a second include internally through autoloading
(interface B), and the "@" is suppressing the errors of the second, since it's
recursive.
That makes sense.
I thought it wasn't really suppressing it since I was seeing the errors in the other use-cases
I mentioned, and I noticed a very old similar report still "Open":
https://bugs.php.net/bug.php?id=73323
so I thought this was indeed a bug which wasn't solved yet.
But yeah, it's not a bug... you may close this report.
Sorry and thank you. :)
------------------------------------------------------------------------
[2018-11-26 18:05:56] requinix@php.net
So the bug you're reporting is that when you use @ to suppress errors, you don't see
errors?
------------------------------------------------------------------------
[2018-11-26 18:00:44] claudio dot luis at aptoide dot com
Description:
------------
Whenever a class or interface is autoloaded through the autoload of another class (internally
recursive autoload), if such class or interface file is not found in the end (no file loaded/found),
no E_ERROR level error is output to the screen (be it console or browser), namely the error
reporting a class or interface to not have been found.
In other words, in cases such as:
class A extends B
and
class A implements B
if neither A and B have been loaded yet, once A is autoloaded, so is B, but if the autoloading of B
fails, no error is output and the program execution simply halts silently, while if the autoloading
of A fails, then the expected error is shown, such as:
"PHP Fatal error: Class 'A' not found in ..."
However, if the file containing class A is explicitly loaded beforehand, like so for example:
include_once 'A.php';
then the same test results in a visible error, such as:
"PHP Fatal error: Interface 'B' not found in ..."
Also, while not shown, in all cases the error is still registered internally and can be fetched with
error_get_last().
Test script:
---------------
//A.php (B.php does not exist)
class A implements B
{
public function doStuff(): void
{
echo "Hello World!";
}
}
//------------------------------------------------------------------
//test.php
//load class and interface files residing in the same directory
spl_autoload_register(function (string $class): void {
@include_once __DIR__ . '/' . $class . '.php';
}, true);
(new A)->doStuff();
Expected result:
----------------
The following error output to the console or browser:
PHP Fatal error: Interface 'B' not found in /test.php on line 6
Actual result:
--------------
No error at all is output, but the program execution is halted.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=77205&edit=1