Skip to content

Commit 6d4c20f

Browse files
Merge branch '3.4' into 4.3
* 3.4: [FrameworkBundle][Config] Ignore exeptions thrown during reflection classes autoload
2 parents 32fa79a + 5d1036e commit 6d4c20f

File tree

1 file changed

+47
-10
lines changed

1 file changed

+47
-10
lines changed

Resource/ClassExistenceResource.php

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,14 @@ public function isFresh($timestamp)
7676

7777
try {
7878
$exists = class_exists($this->resource) || interface_exists($this->resource, false) || trait_exists($this->resource, false);
79-
} catch (\ReflectionException $e) {
80-
if (0 >= $timestamp) {
81-
unset(self::$existsCache[1][$this->resource]);
82-
throw $e;
79+
} catch (\Exception $e) {
80+
try {
81+
self::throwOnRequiredClass($this->resource, $e);
82+
} catch (\ReflectionException $e) {
83+
if (0 >= $timestamp) {
84+
unset(self::$existsCache[1][$this->resource]);
85+
throw $e;
86+
}
8387
}
8488
} finally {
8589
self::$autoloadedClass = $autoloadedClass;
@@ -109,24 +113,57 @@ public function __sleep(): array
109113
}
110114

111115
/**
112-
* @throws \ReflectionException When $class is not found and is required
116+
* Throws a reflection exception when the passed class does not exist but is required.
117+
*
118+
* A class is considered "not required" when it's loaded as part of a "class_exists" or similar check.
119+
*
120+
* This function can be used as an autoload function to throw a reflection
121+
* exception if the class was not found by previous autoload functions.
122+
*
123+
* A previous exception can be passed. In this case, the class is considered as being
124+
* required totally, so if it doesn't exist, a reflection exception is always thrown.
125+
* If it exists, the previous exception is rethrown.
126+
*
127+
* @throws \ReflectionException
113128
*
114129
* @internal
115130
*/
116-
public static function throwOnRequiredClass($class)
131+
public static function throwOnRequiredClass($class, \Exception $previous = null)
117132
{
118-
if (self::$autoloadedClass === $class) {
133+
// If the passed class is the resource being checked, we shouldn't throw.
134+
if (null === $previous && self::$autoloadedClass === $class) {
135+
return;
136+
}
137+
138+
if (class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false)) {
139+
if (null !== $previous) {
140+
throw $previous;
141+
}
142+
119143
return;
120144
}
121-
$e = new \ReflectionException("Class $class not found");
145+
146+
if ($previous instanceof \ReflectionException) {
147+
throw $previous;
148+
}
149+
150+
$e = new \ReflectionException("Class $class not found", 0, $previous);
151+
152+
if (null !== $previous) {
153+
throw $e;
154+
}
155+
122156
$trace = $e->getTrace();
123157
$autoloadFrame = [
124158
'function' => 'spl_autoload_call',
125159
'args' => [$class],
126160
];
127-
$i = 1 + array_search($autoloadFrame, $trace, true);
128161

129-
if (isset($trace[$i]['function']) && !isset($trace[$i]['class'])) {
162+
if (false === $i = array_search($autoloadFrame, $trace, true)) {
163+
throw $e;
164+
}
165+
166+
if (isset($trace[++$i]['function']) && !isset($trace[$i]['class'])) {
130167
switch ($trace[$i]['function']) {
131168
case 'get_class_methods':
132169
case 'get_class_vars':

0 commit comments

Comments
 (0)