Error Identifier: catch.alreadyCaught
Every error reported by PHPStan has an error identifier. Here’s a list of all error identifiers. In PHPStan Pro you can see the error identifier next to each error and filter errors by their identifiers.
Code example #
<?php declare(strict_types = 1);
function doFoo(): void
{
try {
doSomething();
} catch (\Throwable $e) {
} catch (\TypeError $e) {
}
}
Why is it reported? #
PHP evaluates catch blocks in order from top to bottom and enters the first one whose type matches the thrown exception. In the example above, \Throwable is a supertype of \TypeError, so the first catch block will always match any TypeError before the second block is reached. The second catch block is dead code and will never execute.
How to fix it #
Reorder the catch blocks so that more specific exception types come first:
<?php declare(strict_types = 1);
function doFoo(): void
{
try {
doSomething();
- } catch (\Throwable $e) {
-
} catch (\TypeError $e) {
+ // Handle TypeError specifically
+ } catch (\Throwable $e) {
+ // Handle everything else
}
}
Or remove the dead catch block if it is not needed:
<?php declare(strict_types = 1);
function doFoo(): void
{
try {
doSomething();
} catch (\Throwable $e) {
- } catch (\TypeError $e) {
-
}
}
How to ignore this error #
You can use the identifier catch.alreadyCaught to ignore this error using a comment:
// @phpstan-ignore catch.alreadyCaught
codeThatProducesTheError();
You can also use only the identifier key to ignore all errors of the same type in your configuration file in the ignoreErrors parameter:
parameters:
ignoreErrors:
-
identifier: catch.alreadyCaught
Rules that report this error #
- PHPStan\Rules\Exceptions\CatchWithUnthrownExceptionRule [1]