@@ -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 ;
@@ -117,24 +121,57 @@ public function unserialize($serialized)
117121 }
118122
119123 /**
120- * @throws \ReflectionException When $class is not found and is required
124+ * Throws a reflection exception when the passed class does not exist but is required.
125+ *
126+ * A class is considered "not required" when it's loaded as part of a "class_exists" or similar check.
127+ *
128+ * This function can be used as an autoload function to throw a reflection
129+ * exception if the class was not found by previous autoload functions.
130+ *
131+ * A previous exception can be passed. In this case, the class is considered as being
132+ * required totally, so if it doesn't exist, a reflection exception is always thrown.
133+ * If it exists, the previous exception is rethrown.
134+ *
135+ * @throws \ReflectionException
121136 *
122137 * @internal
123138 */
124- public static function throwOnRequiredClass ($ class )
139+ public static function throwOnRequiredClass ($ class, \ Exception $ previous = null )
125140 {
126- if (self ::$ autoloadedClass === $ class ) {
141+ // If the passed class is the resource being checked, we shouldn't throw.
142+ if (null === $ previous && self ::$ autoloadedClass === $ class ) {
143+ return ;
144+ }
145+
146+ if (class_exists ($ class , false ) || interface_exists ($ class , false ) || trait_exists ($ class , false )) {
147+ if (null !== $ previous ) {
148+ throw $ previous ;
149+ }
150+
127151 return ;
128152 }
129- $ e = new \ReflectionException ("Class $ class not found " );
153+
154+ if ($ previous instanceof \ReflectionException) {
155+ throw $ previous ;
156+ }
157+
158+ $ e = new \ReflectionException ("Class $ class not found " , 0 , $ previous );
159+
160+ if (null !== $ previous ) {
161+ throw $ e ;
162+ }
163+
130164 $ trace = $ e ->getTrace ();
131165 $ autoloadFrame = [
132166 'function ' => 'spl_autoload_call ' ,
133167 'args ' => [$ class ],
134168 ];
135- $ i = 1 + array_search ($ autoloadFrame , $ trace , true );
136169
137- if (isset ($ trace [$ i ]['function ' ]) && !isset ($ trace [$ i ]['class ' ])) {
170+ if (false === $ i = array_search ($ autoloadFrame , $ trace , true )) {
171+ throw $ e ;
172+ }
173+
174+ if (isset ($ trace [++$ i ]['function ' ]) && !isset ($ trace [$ i ]['class ' ])) {
138175 switch ($ trace [$ i ]['function ' ]) {
139176 case 'get_class_methods ' :
140177 case 'get_class_vars ' :
0 commit comments