website/errors/throws.notCovariant.md
<?php declare(strict_types = 1);
class Foo
{
/**
* @throws \LogicException
*/
public function doSomething(): void
{
}
}
class Bar extends Foo
{
/**
* @throws \RuntimeException
*/
public function doSomething(): void
{
}
}
The @throws type declared on an overriding method is not covariant with the @throws type of the parent method. Covariance means the child's throw type must be the same as or a subtype of the parent's throw type.
In the example above, the parent declares @throws \LogicException, but the child declares @throws \RuntimeException. Since RuntimeException does not extend LogicException, this violates the covariance principle. Callers that catch LogicException based on the parent's contract would not catch RuntimeException.
This rule is controlled by the exceptions.check.throwTypeCovariance configuration option.
Change the child's @throws tag to a subtype of the parent's throw type:
class Bar extends Foo
{
/**
- * @throws \RuntimeException
+ * @throws \BadFunctionCallException
*/
public function doSomething(): void
{
}
}
BadFunctionCallException is a subtype of LogicException, so it satisfies the covariance requirement.
Alternatively, if the method truly does not throw, use @throws void:
class Bar extends Foo
{
/**
- * @throws \RuntimeException
+ * @throws void
*/
public function doSomething(): void
{
}
}