Skip to content

Fix #11427: Wrong "dead catch" error, side effects of ArrayAccess not considered#4910

Open
phpstan-bot wants to merge 3 commits into2.1.xfrom
create-pull-request/patch-6518lna
Open

Fix #11427: Wrong "dead catch" error, side effects of ArrayAccess not considered#4910
phpstan-bot wants to merge 3 commits into2.1.xfrom
create-pull-request/patch-6518lna

Conversation

@phpstan-bot
Copy link
Collaborator

Summary

When using array syntax on ArrayAccess objects, PHP implicitly calls offsetGet, offsetExists, offsetUnset, or offsetSet. These methods can throw exceptions, but only offsetSet (array assignment) was generating throw points in the analysis. This caused false "dead catch" errors when catching exceptions from isset($x[1]), $x[1] reads, and unset($x[1]) on ArrayAccess implementations.

Changes

  • src/Analyser/NodeScopeResolver.php: Added synthetic MethodCall throw point collection for:
    • offsetGet in the ArrayDimFetch expression handler (reading $x[1])
    • offsetUnset in the Unset_ statement handler (for unset($x[1]))
    • offsetExists in the Isset_ expression handler (for isset($x[1]))
  • tests/PHPStan/Rules/Exceptions/data/bug-11427.php: Regression test with ArrayAccess class whose methods throw
  • tests/PHPStan/Rules/Exceptions/CatchWithUnthrownExceptionRuleTest.php: Added testBug11427 method
  • CLAUDE.md: Documented the ArrayAccess throw point synthesis pattern

Root cause

NodeScopeResolver already synthesized a MethodCall to offsetSet when processing array assignments on ArrayAccess objects (line ~6291), which properly generated throw points for dead-catch analysis. However, the same pattern was missing for the other three ArrayAccess operations: offsetGet (array read), offsetUnset (unset), and offsetExists (isset). Without these synthetic method calls, their potential exceptions were invisible to the dead-catch rule.

Test

The regression test creates an ArrayAccess class where all four offset methods throw \Exception, then wraps each operation in try/catch blocks. Before the fix, 3 of 4 catch blocks were incorrectly reported as dead catches. After the fix, no errors are reported.

Fixes phpstan/phpstan#11427

ondrejmirtes and others added 3 commits February 12, 2026 19:29
- Synthesize offsetGet throw points in ArrayDimFetch handler for ArrayAccess objects
- Synthesize offsetUnset throw points in Unset_ handler for ArrayAccess objects
- Synthesize offsetExists throw points in Isset_ handler for ArrayAccess objects
- offsetSet was already handled; this brings the other three operations to parity
- New regression test in tests/PHPStan/Rules/Exceptions/data/bug-11427.php
Automated fix attempt 1 for CI failures.
Automated fix attempt 2 for CI failures.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wrong "dead catch" error, side effects of ArrayAccess not considered

2 participants