diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php index c4779156a9e..a5dc24d171c 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php @@ -97,7 +97,11 @@ public static function fetch( if ($premixin_method_id->method_name === 'getcode' && $premixin_method_id->fq_class_name !== Exception::class - && in_array(Throwable::class, $class_storage->class_implements)) { + && ( + $codebase->classImplements($premixin_method_id->fq_class_name, Throwable::class) + || $codebase->interfaceExtends($premixin_method_id->fq_class_name, Throwable::class) + ) + ) { if ($premixin_method_id->fq_class_name === PDOException::class) { return Type::getString(); } else { diff --git a/tests/ReturnTypeProvider/ExceptionCodeTest.php b/tests/ReturnTypeProvider/ExceptionCodeTest.php index ccc8ea10db5..84e8acb28e5 100644 --- a/tests/ReturnTypeProvider/ExceptionCodeTest.php +++ b/tests/ReturnTypeProvider/ExceptionCodeTest.php @@ -35,14 +35,23 @@ function f(\PDOException $e): string { ', [], ]; - yield 'Exception' => [ + yield 'CustomThrowable' => [ + 'getCode(); + ', + ['$code' => 'int'], + ]; + yield 'Throwable' => [ 'getCode(); ', ['$code' => 'int|string'], ]; - yield 'Throwable' => [ + yield 'Exception' => [ 'getCode();