@@ -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