Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbf467cc

Browse files
fancywebnicolas-grekas
authored andcommitted
[FrameworkBundle][Config] Ignore exeptions thrown during reflection classes autoload
1 parent3dab7c9 commitbf467cc

File tree

12 files changed

+241
-32
lines changed

12 files changed

+241
-32
lines changed

‎src/Symfony/Bundle/FrameworkBundle/CacheWarmer/AbstractPhpFileCacheWarmer.php‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
useSymfony\Component\Cache\Adapter\ArrayAdapter;
1717
useSymfony\Component\Cache\Adapter\PhpArrayAdapter;
1818
useSymfony\Component\Cache\Adapter\ProxyAdapter;
19+
useSymfony\Component\Config\Resource\ClassExistenceResource;
1920
useSymfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
2021

2122
/**
@@ -54,13 +55,13 @@ public function warmUp($cacheDir)
5455
{
5556
$arrayAdapter =newArrayAdapter();
5657

57-
spl_autoload_register([PhpArrayAdapter::class,'throwOnRequiredClass']);
58+
spl_autoload_register([ClassExistenceResource::class,'throwOnRequiredClass']);
5859
try {
5960
if (!$this->doWarmUp($cacheDir,$arrayAdapter)) {
6061
return;
6162
}
6263
}finally {
63-
spl_autoload_unregister([PhpArrayAdapter::class,'throwOnRequiredClass']);
64+
spl_autoload_unregister([ClassExistenceResource::class,'throwOnRequiredClass']);
6465
}
6566

6667
// the ArrayAdapter stores the values serialized
@@ -82,6 +83,14 @@ protected function warmUpPhpArrayAdapter(PhpArrayAdapter $phpArrayAdapter, array
8283
$phpArrayAdapter->warmUp($values);
8384
}
8485

86+
protectedfunctionignoreAutoloadException($class,\Exception$exception)
87+
{
88+
try {
89+
ClassExistenceResource::throwOnRequiredClass($class,$exception);
90+
}catch (\ReflectionException$e) {
91+
}
92+
}
93+
8594
/**
8695
* @param string $cacheDir
8796
* @param ArrayAdapter $arrayAdapter

‎src/Symfony/Bundle/FrameworkBundle/CacheWarmer/AnnotationsCacheWarmer.php‎

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,8 @@ protected function doWarmUp($cacheDir, ArrayAdapter $arrayAdapter)
6464
}
6565
try {
6666
$this->readAllComponents($reader,$class);
67-
}catch (\ReflectionException$e) {
68-
// ignore failing reflection
69-
}catch (AnnotationException$e) {
70-
/*
71-
* Ignore any AnnotationException to not break the cache warming process if an Annotation is badly
72-
* configured or could not be found / read / etc.
73-
*
74-
* In particular cases, an Annotation in your code can be used and defined only for a specific
75-
* environment but is always added to the annotations.map file by some Symfony default behaviors,
76-
* and you always end up with a not found Annotation.
77-
*/
67+
}catch (\Exception$e) {
68+
$this->ignoreAutoloadException($class,$e);
7869
}
7970
}
8071

@@ -84,14 +75,32 @@ protected function doWarmUp($cacheDir, ArrayAdapter $arrayAdapter)
8475
privatefunctionreadAllComponents(Reader$reader,$class)
8576
{
8677
$reflectionClass =new \ReflectionClass($class);
87-
$reader->getClassAnnotations($reflectionClass);
78+
79+
try {
80+
$reader->getClassAnnotations($reflectionClass);
81+
}catch (AnnotationException$e) {
82+
/*
83+
* Ignore any AnnotationException to not break the cache warming process if an Annotation is badly
84+
* configured or could not be found / read / etc.
85+
*
86+
* In particular cases, an Annotation in your code can be used and defined only for a specific
87+
* environment but is always added to the annotations.map file by some Symfony default behaviors,
88+
* and you always end up with a not found Annotation.
89+
*/
90+
}
8891

8992
foreach ($reflectionClass->getMethods()as$reflectionMethod) {
90-
$reader->getMethodAnnotations($reflectionMethod);
93+
try {
94+
$reader->getMethodAnnotations($reflectionMethod);
95+
}catch (AnnotationException$e) {
96+
}
9197
}
9298

9399
foreach ($reflectionClass->getProperties()as$reflectionProperty) {
94-
$reader->getPropertyAnnotations($reflectionProperty);
100+
try {
101+
$reader->getPropertyAnnotations($reflectionProperty);
102+
}catch (AnnotationException$e) {
103+
}
95104
}
96105
}
97106
}

‎src/Symfony/Bundle/FrameworkBundle/CacheWarmer/SerializerCacheWarmer.php‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ protected function doWarmUp($cacheDir, ArrayAdapter $arrayAdapter)
5656
foreach ($loader->getMappedClasses()as$mappedClass) {
5757
try {
5858
$metadataFactory->getMetadataFor($mappedClass);
59-
}catch (\ReflectionException$e) {
60-
// ignore failing reflection
6159
}catch (AnnotationException$e) {
6260
// ignore failing annotations
61+
}catch (\Exception$e) {
62+
$this->ignoreAutoloadException($mappedClass,$e);
6363
}
6464
}
6565
}

‎src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ protected function doWarmUp($cacheDir, ArrayAdapter $arrayAdapter)
6161
if ($metadataFactory->hasMetadataFor($mappedClass)) {
6262
$metadataFactory->getMetadataFor($mappedClass);
6363
}
64-
}catch (\ReflectionException$e) {
65-
// ignore failing reflection
6664
}catch (AnnotationException$e) {
6765
// ignore failing annotations
66+
}catch (\Exception$e) {
67+
$this->ignoreAutoloadException($mappedClass,$e);
6868
}
6969
}
7070
}

‎src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/AnnotationsCacheWarmerTest.php‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,54 @@ public function testAnnotationsCacheWarmerWithDebugEnabled()
8686
$reader->getPropertyAnnotations($refClass->getProperty('cacheDir'));
8787
}
8888

89+
/**
90+
* Test that the cache warming process is not broken if a class loader
91+
* throws an exception (on class / file not found for example).
92+
*/
93+
publicfunctiontestClassAutoloadException()
94+
{
95+
$this->assertFalse(class_exists($annotatedClass ='C\C\C',false));
96+
97+
file_put_contents($this->cacheDir.'/annotations.map',sprintf('<?php return %s;',var_export([$annotatedClass],true)));
98+
$warmer =newAnnotationsCacheWarmer(newAnnotationReader(),tempnam($this->cacheDir,__FUNCTION__),newArrayAdapter());
99+
100+
spl_autoload_register($classLoader =function ($class)use ($annotatedClass) {
101+
if ($class ===$annotatedClass) {
102+
thrownew \DomainException('This exception should be caught by the warmer.');
103+
}
104+
},true,true);
105+
106+
$warmer->warmUp($this->cacheDir);
107+
108+
spl_autoload_unregister($classLoader);
109+
}
110+
111+
/**
112+
* Test that the cache warming process is broken if a class loader throws an
113+
* exception but that is unrelated to the class load.
114+
*/
115+
publicfunctiontestClassAutoloadExceptionWithUnrelatedException()
116+
{
117+
$this->expectException(\DomainException::class);
118+
$this->expectExceptionMessage('This exception should not be caught by the warmer.');
119+
120+
$this->assertFalse(class_exists($annotatedClass ='AClassThatDoesNotExist_FWB_CacheWarmer_AnnotationsCacheWarmerTest',false));
121+
122+
file_put_contents($this->cacheDir.'/annotations.map',sprintf('<?php return %s;',var_export([$annotatedClass],true)));
123+
$warmer =newAnnotationsCacheWarmer(newAnnotationReader(),tempnam($this->cacheDir,__FUNCTION__),newArrayAdapter());
124+
125+
spl_autoload_register($classLoader =function ($class)use ($annotatedClass) {
126+
if ($class ===$annotatedClass) {
127+
eval('class'.$annotatedClass.'{}');
128+
thrownew \DomainException('This exception should not be caught by the warmer.');
129+
}
130+
},true,true);
131+
132+
$warmer->warmUp($this->cacheDir);
133+
134+
spl_autoload_unregister($classLoader);
135+
}
136+
89137
/**
90138
* @return MockObject|Reader
91139
*/

‎src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/SerializerCacheWarmerTest.php‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,58 @@ public function testWarmUpWithoutLoader()
7777
$this->assertIsArray($values);
7878
$this->assertCount(0,$values);
7979
}
80+
81+
/**
82+
* Test that the cache warming process is not broken if a class loader
83+
* throws an exception (on class / file not found for example).
84+
*/
85+
publicfunctiontestClassAutoloadException()
86+
{
87+
if (!class_exists(CacheClassMetadataFactory::class) || !method_exists(XmlFileLoader::class,'getMappedClasses') || !method_exists(YamlFileLoader::class,'getMappedClasses')) {
88+
$this->markTestSkipped('The Serializer default cache warmer has been introduced in the Serializer Component version 3.2.');
89+
}
90+
91+
$this->assertFalse(class_exists($mappedClass ='AClassThatDoesNotExist_FWB_CacheWarmer_SerializerCacheWarmerTest',false));
92+
93+
$warmer =newSerializerCacheWarmer([newYamlFileLoader(__DIR__.'/../Fixtures/Serialization/Resources/does_not_exist.yaml')],tempnam(sys_get_temp_dir(),__FUNCTION__),newArrayAdapter());
94+
95+
spl_autoload_register($classLoader =function ($class)use ($mappedClass) {
96+
if ($class ===$mappedClass) {
97+
thrownew \DomainException('This exception should be caught by the warmer.');
98+
}
99+
},true,true);
100+
101+
$warmer->warmUp('foo');
102+
103+
spl_autoload_unregister($classLoader);
104+
}
105+
106+
/**
107+
* Test that the cache warming process is broken if a class loader throws an
108+
* exception but that is unrelated to the class load.
109+
*/
110+
publicfunctiontestClassAutoloadExceptionWithUnrelatedException()
111+
{
112+
$this->expectException(\DomainException::class);
113+
$this->expectExceptionMessage('This exception should not be caught by the warmer.');
114+
115+
if (!class_exists(CacheClassMetadataFactory::class) || !method_exists(XmlFileLoader::class,'getMappedClasses') || !method_exists(YamlFileLoader::class,'getMappedClasses')) {
116+
$this->markTestSkipped('The Serializer default cache warmer has been introduced in the Serializer Component version 3.2.');
117+
}
118+
119+
$this->assertFalse(class_exists($mappedClass ='AClassThatDoesNotExist_FWB_CacheWarmer_SerializerCacheWarmerTest',false));
120+
121+
$warmer =newSerializerCacheWarmer([newYamlFileLoader(__DIR__.'/../Fixtures/Serialization/Resources/does_not_exist.yaml')],tempnam(sys_get_temp_dir(),__FUNCTION__),newArrayAdapter());
122+
123+
spl_autoload_register($classLoader =function ($class)use ($mappedClass) {
124+
if ($class ===$mappedClass) {
125+
eval('class'.$mappedClass.'{}');
126+
thrownew \DomainException('This exception should not be caught by the warmer.');
127+
}
128+
},true,true);
129+
130+
$warmer->warmUp('foo');
131+
132+
spl_autoload_unregister($classLoader);
133+
}
80134
}

‎src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ValidatorCacheWarmerTest.php‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,54 @@ public function testWarmUpWithoutLoader()
107107
$this->assertIsArray($values);
108108
$this->assertCount(0,$values);
109109
}
110+
111+
/**
112+
* Test that the cache warming process is not broken if a class loader
113+
* throws an exception (on class / file not found for example).
114+
*/
115+
publicfunctiontestClassAutoloadException()
116+
{
117+
$this->assertFalse(class_exists($mappedClass ='AClassThatDoesNotExist_FWB_CacheWarmer_ValidatorCacheWarmerTest',false));
118+
119+
$validatorBuilder =newValidatorBuilder();
120+
$validatorBuilder->addYamlMapping(__DIR__.'/../Fixtures/Validation/Resources/does_not_exist.yaml');
121+
$warmer =newValidatorCacheWarmer($validatorBuilder,tempnam(sys_get_temp_dir(),__FUNCTION__),newArrayAdapter());
122+
123+
spl_autoload_register($classloader =function ($class)use ($mappedClass) {
124+
if ($class ===$mappedClass) {
125+
thrownew \DomainException('This exception should be caught by the warmer.');
126+
}
127+
},true,true);
128+
129+
$warmer->warmUp('foo');
130+
131+
spl_autoload_unregister($classloader);
132+
}
133+
134+
/**
135+
* Test that the cache warming process is broken if a class loader throws an
136+
* exception but that is unrelated to the class load.
137+
*/
138+
publicfunctiontestClassAutoloadExceptionWithUnrelatedException()
139+
{
140+
$this->expectException(\DomainException::class);
141+
$this->expectExceptionMessage('This exception should not be caught by the warmer.');
142+
143+
$this->assertFalse(class_exists($mappedClass ='AClassThatDoesNotExist_FWB_CacheWarmer_ValidatorCacheWarmerTest',false));
144+
145+
$validatorBuilder =newValidatorBuilder();
146+
$validatorBuilder->addYamlMapping(__DIR__.'/../Fixtures/Validation/Resources/does_not_exist.yaml');
147+
$warmer =newValidatorCacheWarmer($validatorBuilder,tempnam(sys_get_temp_dir(),__FUNCTION__),newArrayAdapter());
148+
149+
spl_autoload_register($classLoader =function ($class)use ($mappedClass) {
150+
if ($class ===$mappedClass) {
151+
eval('class'.$mappedClass.'{}');
152+
thrownew \DomainException('This exception should not be caught by the warmer.');
153+
}
154+
},true,true);
155+
156+
$warmer->warmUp('foo');
157+
158+
spl_autoload_unregister($classLoader);
159+
}
110160
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
AClassThatDoesNotExist_FWB_CacheWarmer_SerializerCacheWarmerTest:~
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
AClassThatDoesNotExist_FWB_CacheWarmer_ValidatorCacheWarmerTest:~

‎src/Symfony/Bundle/FrameworkBundle/composer.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"symfony/cache":"~3.4|~4.0",
2222
"symfony/class-loader":"~3.2",
2323
"symfony/dependency-injection":"^3.4.24|^4.2.5",
24-
"symfony/config":"~3.4|~4.0",
24+
"symfony/config":"^3.4.30|~4.2.11|^4.3.3",
2525
"symfony/debug":"~2.8|~3.0|~4.0",
2626
"symfony/event-dispatcher":"~3.4|~4.0",
2727
"symfony/http-foundation":"^3.3.11|~4.0",

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp