-
-
Notifications
You must be signed in to change notification settings - Fork 934
Description
Feature request
PHPStan (even with missingCheckedExceptionInThrows enabled) allows an implementation/override to declare a wider exception type than its interface or parent. This violates the Liskov Substitution Principle: if an interface promises only LogicException, an implementation must not declare or effectively throw Exception.
interface Foo {
/**
* @throws LogicException
*/
public function run(): void;
}
final class Bar implements Foo {
/**
* @throws Exception // ← wider than LogicException
*/
public function run(): void {
throw new Exception('boom'); // also too wide
}
}PHPStan should report an error when an overriding method’s @throws includes any type that is not the same as or a subtype of a parent-declared thrown type. Narrowing (e.g., InvalidArgumentException for LogicException) is fine; widening (Exception|LogicException, Throwable, Exception) should fail.
Adding a check would allow fewer surprising runtime failures for callers relying on the interface’s narrower @throws.
Did PHPStan help you today? Did it make you happy in any way?
PHPStan often helps me catch contract violations again today. This feature would make it even more consistent and delightful to use