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
final is a slight hint that this situation may happen. 'Slight hint' refers to the fact that most code bases do not use final consistently. I think this is the most important curlpit here.
- A class which is tagged as
abstract is a stronger hint that this may happen.
- A class tagged as
final would disallow overriding the method, making the error message valid.
- Same applies to
final on the method.
- And to
private methods.
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
Bug report
A method in a base class may be annotated with
@throws SomeExceptionto express that derived classes are allowed to throw such exceptions:This informs users of the base class that code calling the method has to expect the exception:
However, PhpStan reports the
@throwsannotation as an error:Some thoughts around this:
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.abstractis a stronger hint that this may happen.finalwould disallow overriding the method, making the error message valid.finalon the method.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