-
-
Notifications
You must be signed in to change notification settings - Fork 934
Closed
Labels
Milestone
Description
Bug report
A method in a base class may be annotated with @throws SomeException to express that derived classes are allowed to throw such exceptions:
abstract class Base {
/**
* @throws \LogicException
*/
public function f(): void {
}
}
class Derived extends Base {
public function f(): void {
throw new \LogicException();
}
}This informs users of the base class that code calling the method has to expect the exception:
function g(Base $obj): void {
try {
$obj->f();
} catch (\LogicException $e) {
// Not a dead catch: Base::f itself doesn't throw,
// but it may be overridden to throw
}
}However, PhpStan reports the @throws annotation as an error:
Method Base::f() has LogicException in PHPDoc @throws tag but it's not thrown.
Some thoughts around this:
- A class which is not
finalis a slight hint that this situation may happen. 'Slight hint' refers to the fact that most code bases do not usefinalconsistently. I think this is the most important curlpit here. - A class which is tagged as
abstractis a stronger hint that this may happen. - A class tagged as
finalwould disallow overriding the method, making the error message valid. - Same applies to
finalon the method. - And to
privatemethods.
Code snippet that reproduces the problem
https://phpstan.org/r/f7f8735c-2620-4cfa-88e1-f4442f36214f
Expected output
No error reported.
Did PHPStan help you today? Did it make you happy in any way?
No response