Skip to content

fix: restore PHPStan dependencies and fix unhandled EventType matches - #85

Closed
Baspa wants to merge 2 commits into
mainfrom
fix/phpstan-config
Closed

fix: restore PHPStan dependencies and fix unhandled EventType matches#85
Baspa wants to merge 2 commits into
mainfrom
fix/phpstan-config

Conversation

@Baspa

@Baspa Baspa commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Problem

composer analyse and the PHPStan CI workflow have both been failing since the Filament v4 upgrade (#49).

That PR dropped nunomaduro/larastan, phpstan/extension-installer, phpstan/phpstan-deprecation-rules and phpstan/phpstan-phpunit from require-dev, but left phpstan.neon.dist, phpstan-baseline.neon, the analyse script and .github/workflows/phpstan.yml in place. So:

$ composer analyse
sh: vendor/bin/phpstan: No such file or directory
Script vendor/bin/phpstan analyse handling the analyse event returned with error code 127

The workflow runs ./vendor/bin/phpstan --error-format=github, which has the same problem — the job has been red (or skipped as a missing binary) for every push since.

Fix

Restore the dev dependencies at versions matching PHPStan 2:

  • larastan/larastan: ^3.0 (the package was renamed from nunomaduro/larastan)
  • phpstan/extension-installer: ^1.3
  • phpstan/phpstan-deprecation-rules: ^2.0

phpstan.neon.dist itself needed no changes. checkOctaneCompatibility and checkModelProperties are still valid Larastan 3 parameters — they only appeared invalid without extension-installer present to register Larastan's extension.neon.

composer.json also picks up a trailing newline, which it was missing.

Real bug this surfaced

With PHPStan actually running, it found three genuine match.unhandled errors:

  • src/Resources/EventResource.php:92
  • src/Resources/EventResource.php:218
  • src/Resources/MailResource.php:225

All three are the badge-colour closure:

->color(fn (EventType $state): string => match ($state) {
    EventType::DELIVERED => 'success',
    EventType::CLICKED => 'clicked',
    EventType::OPENED => 'info',
    EventType::SOFT_BOUNCED => 'danger',
    EventType::HARD_BOUNCED => 'danger',
    EventType::COMPLAINED => 'warning',
    EventType::UNSUBSCRIBED => 'danger',
    EventType::ACCEPTED => 'success',
})

EventType has 29 cases, only 8 are handled, and there is no default arm. Any other event type — transient, blocked, spam_complaint, dns_error, template_rendering_failed, unknown, and the rest of the Postmark-style set — throws UnhandledMatchError when the badge renders, which 500s the events table, the event view page and the mail view page.

Fixed by adding default => 'gray' to all three.

Verification

$ composer analyse
 [OK] No errors

$ vendor/bin/pest
  Tests:    4 passed (8 assertions)

$ vendor/bin/pint --test
  PASS

Note

The three matches are identical copies of each other, which is how two of them stayed unnoticed. Consolidating them behind a single helper would be worthwhile, but EventType lives in backstage/laravel-mails, so the natural home for a color() method is that package rather than this one. Left alone here.

Baspa added 2 commits July 30, 2026 09:22
EventType has 29 cases but the badge colour matches handled only 8 with no
default arm, so any other event type threw UnhandledMatchError and 500'd the
events pages.
@Baspa Baspa self-assigned this Jul 30, 2026
@Baspa

Baspa commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by backstagephp/cms#299.

packages/mails is subtree-split from the backstagephp/cms monorepo, so fixes need to land there to survive the next split. Same changes, plus the CI resolution fix that was blocking this PR's checks.

@Baspa Baspa closed this Jul 30, 2026
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.

1 participant