-
-
Notifications
You must be signed in to change notification settings - Fork 294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proxy's __debugInfo()
must not have side effects
#964
Comments
P.S.: Wrapping |
Shouldn't this be reported to Xdebug instead? |
Yeah, maybe. I originally did not find a way to reproduce it without the Doctrine proxy involved, but I just found that this also triggers it: class test
{
public function __debugInfo()
{
throw new Exception('X');
return [];
}
}
var_dump(new test); So the problem is that Doctrine throws here: There is only one thing I don't understand, and that is where If I comment out either of those two lines, the problem disappears. Digging a bit deeper, I noticed that if I change the code in try {
throw EntityNotFoundException::fromClassNameAndIdentifier(
$classMetadata->getName(),
$this->identifierFlattener->flattenIdentifier($classMetadata, $identifier)
);
} catch (EntityNotFoundException $e) {
die('Caught');
} The exception does not get caught. I'm not sure, but it kind of seems like there's something funky going on on the doctrine side, too. Anyway, I also opened https://bugs.xdebug.org/view.php?id=2100 on the xdebug side |
after some more research, I'm pretty sure now that this is really only an xdebug issue, closing this one. |
Thanks! |
Short update: I've since discovered php/php-src#7922 which states that the Fatal Error mentioned above is actually a current core PHP behavior/bug. The /**
* {@inheritDoc}
*/
public function __debugInfo()
{
$this->__initializer__ && $this->__initializer__->__invoke($this, '__debugInfo', []);
return parent::__debugInfo();
} and So I wonder: would it make sense to open a new feature request or similar to add a |
Makes sense to me. |
I can't really fix this on the @xdebug side, as it expects (quite reasonably) that |
__debugInfo()
must not have side effects
changed the title to reflect the latest findings |
We should catch the exception and return a debug info including the exception message. This must be in doctrine/common ProxyGenerator |
ContextI only got to this discussion because of recent twitter convos about My 2 centsDon't introduce The fact that a proxied object includes Solution: complete removal of Regardless off the existence of |
My two cents:
But again: Why not just add a |
Because it actively hurts debugging
Totally on board with this.
Even more side-effects: breaks exception traps in the debugger, causes autoloading, creates objects, increases memory usage, potentially leads to even more I/O. Don't. |
Well, in my case, it helps debugging, because without it
The In general, if you're of the opinion that |
On 4 August 2022 14:56:30 BST, flack ***@***.***> wrote:
> Because it actively hurts debugging
Well, in my case, it helps debugging, because without it `var_dump($entity)` takes 1-2 minutes
Debugging is done with a debugger, not by introducing echoing statements in your code.
The problem that I pointed @Ocramius to on twitter is that debugInfo should not have side effects. If you want to do parent calls in it, then you need to try/catch that yourself so exceptions can never leak out of every implementation that you make as __debugInfo calls
cheers
Derick
|
Sure, why not. The way I actually discovered this memory usage issue was because after migrating some code to Doctrine my test server kept dying, because in certain situations it would write entities to a log file, which worked fine in the old system, but due to the different structure in the doctrine entities there was this huge memory blowup. I'm sure that all of that can be avoided by following best practices and so on, but it is still a footgun that you could trigger accidentally, so why make life harder for us poor frontline devs? |
Mostly because adding even more layers would make your life even worse, plus worsening things on this end too :-) |
Yeah, the less layers, the better, I definitely agree with that. But just to circle back to my original problem: I have code roughly equivalent to this: function show_name($entity) {
echo $entity->name;
}
try {
$proxy = $em->getReference($my_classname, $this_id_does_not_exist);
show_name($proxy);
} catch (Exception $e) {
echo 'Entity could not be loaded: ' . $e->getMessage();
} This works fine in production. If I enable the |
What do you guys think about having public function __debugInfo()
{
if (!$this->__isInitialized()) {
return array_keys(get_object_vars($this)); // or maybe just hardcode what we want
}
return parent::__debugInfo();
} That way, |
That makes debugging harder, as it is now not clear which properties are set, which are Firm no on implementing any of this, from my end. |
OK, fine. But currently Doctrine generates code that throws an Exception in a place where PHP simply does not allow/support throwing exceptions. That needs to be addressed somehow |
It throws an exception for invalid proxy references, because of the That is still a smaller side-effect than shadowing the entire structure: it's an acceptable trade-off, IMO, even if annoying. I think the best/safest way forward is preventing proxying objects that implement |
We should catch the exception and render that into the debug info |
It throws an exception that cannot be caught. As soon as |
Bug Report
Summary
I'm using Entity classes which have the magic
__debugInfo()
method defined. When I try to load a reference to a nonexistant Entity andvar_dump
it with the following code:the program dies
Current behavior
I get the following error (edited for readability):
How to reproduce
You need PHP 8 or greater and Xdebug loaded. Without xdebug, it works, and with xdebug it works in PHP 7.4 and below. I can try to make some minimal reproduction if it's necessary, for a quick reproduction, you can run the tests of https://github.com/flack/midgard-portable. The result will look like here: https://scrutinizer-ci.com/g/flack/midgard-portable/inspections/464a6111-e297-4cbb-9637-e90870531345
Expected behavior
It should work like it does in PHP 7.x
The text was updated successfully, but these errors were encountered: