From 58398f576f609e893ed3e029e34c2cb4d04fc9ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vaidas=20La=C5=BEauskas?= Date: Fri, 21 Apr 2023 14:49:28 +0300 Subject: [PATCH] Restore document proxy state to uninitialized on load exception --- lib/Doctrine/ORM/Proxy/ProxyFactory.php | 13 ++++++++- .../Tests/ORM/Proxy/ProxyFactoryTest.php | 28 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/lib/Doctrine/ORM/Proxy/ProxyFactory.php b/lib/Doctrine/ORM/Proxy/ProxyFactory.php index fe19c7d71e1..2ba41caba72 100644 --- a/lib/Doctrine/ORM/Proxy/ProxyFactory.php +++ b/lib/Doctrine/ORM/Proxy/ProxyFactory.php @@ -21,6 +21,7 @@ use ReflectionProperty; use Symfony\Component\VarExporter\ProxyHelper; use Symfony\Component\VarExporter\VarExporter; +use Throwable; use function array_flip; use function str_replace; @@ -204,7 +205,17 @@ private function createInitializer(ClassMetadata $classMetadata, EntityPersister $identifier = $classMetadata->getIdentifierValues($proxy); - if ($entityPersister->loadById($identifier, $proxy) === null) { + try { + $entity = $entityPersister->loadById($identifier, $proxy); + } catch (Throwable $exception) { + $proxy->__setInitializer($initializer); + $proxy->__setCloner($cloner); + $proxy->__setInitialized(false); + + throw $exception; + } + + if ($entity === null) { $proxy->__setInitializer($initializer); $proxy->__setCloner($cloner); $proxy->__setInitialized(false); diff --git a/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php b/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php index 8342058a701..804cbbe040e 100644 --- a/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php +++ b/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php @@ -21,6 +21,7 @@ use Doctrine\Tests\Models\ECommerce\ECommerceFeature; use Doctrine\Tests\OrmTestCase; use Doctrine\Tests\PHPUnitCompatibility\MockBuilderCompatibilityTools; +use Exception; use ReflectionProperty; use stdClass; @@ -145,6 +146,33 @@ public function testFailedProxyLoadingDoesNotMarkTheProxyAsInitialized(): void self::assertFalse($proxy->__isInitialized()); } + public function testExceptionOnProxyLoadingDoesNotMarkTheProxyAsInitialized(): void + { + $persister = $this + ->getMockBuilderWithOnlyMethods(BasicEntityPersister::class, ['load', 'getClassMetadata']) + ->disableOriginalConstructor() + ->getMock(); + $this->uowMock->setEntityPersister(ECommerceFeature::class, $persister); + + $proxy = $this->proxyFactory->getProxy(ECommerceFeature::class, ['id' => 42]); + assert($proxy instanceof Proxy); + + $exception = new Exception('Literally any kind of connection exception'); + + $persister + ->expects(self::atLeastOnce()) + ->method('load') + ->will(self::throwException($exception)); + + try { + $proxy->getDescription(); + self::fail('An exception was expected to be raised'); + } catch (Exception $exception) { + } + + self::assertFalse($proxy->__isInitialized(), 'The proxy should not be initialized'); + } + /** @group DDC-2432 */ public function testFailedProxyCloningDoesNotMarkTheProxyAsInitialized(): void {