Skip to content

fix: preserve failure cause in CliLoginTokenAuthenticator - #53

Open
turegjorup wants to merge 1 commit into
developfrom
fix/cli-authenticator-preserves-cause
Open

fix: preserve failure cause in CliLoginTokenAuthenticator#53
turegjorup wants to merge 1 commit into
developfrom
fix/cli-authenticator-preserves-cause

Conversation

@turegjorup

Copy link
Copy Markdown
Contributor

Summary

CliLoginTokenAuthenticator discarded the cause of every CLI login failure. onAuthenticationFailure() threw a bare AuthenticationException('Error occurred validating login token') with no message and no previous, and the CacheException|TokenNotFoundException catch in authenticate() had no variable at all — so a cache outage was indistinguishable from an expired token in the logs.

Both now chain the cause via previous, mirroring the fix applied to OpenIdLoginAuthenticator in #52. Symfony's security component still renders only the safe message key to the user.

This is the sibling half of #52: the two authenticators had drifted, and only one of them was fixed.

Files Changed

  • src/Security/CliLoginTokenAuthenticator.php - chain previous in onAuthenticationFailure(); give the CacheException|TokenNotFoundException catch a variable and pass it as previous; document the CustomUserMessageAuthenticationException that authenticate() already throws
  • tests/Security/CliLoginTokenAuthenticatorTest.php - assert the chained cause on both catch paths and on onAuthenticationFailure(), including that the cause's code is preserved
  • CHANGELOG.md - entry under [Unreleased] / Fixed

Note on the docblock: authenticate() declared only @throws UsernameDoesNotExistException, so PHPStan read the tests' new catch (CustomUserMessageAuthenticationException) blocks as dead code. The docblock was incomplete — the method throws that type directly in its own body — so the fix is to document it rather than add a catch.neverThrown ignore. This follows LoginController::login(), which already documents its framework concretes.

Test Plan

  • task test:coverage — all tests pass, coverage stays at 100% (9/9 classes, 27/27 methods, 261/261 lines)
  • task test:mutation — 115/115 mutants killed, Covered Code MSI 100% (threshold 95)
  • task analyze:php — PHPStan max level + custom exception-contract rules: no errors; the new throw satisfies WrappedExceptionChainsPrevious, and no new ignores were added
  • task test:matrix — PHP 8.3/8.4/8.5 × prefer-lowest/prefer-stable: all 6 combinations pass
  • task lint:php, lint:markdown, lint:yaml, composer validate --strict, composer audit — all clean

onAuthenticationFailure() discarded the cause entirely, and the
CacheException/TokenNotFoundException catch in authenticate() had no
variable, so the underlying failure was unrecoverable from logs. Both now
chain the cause via previous, mirroring OpenIdLoginAuthenticator.

Also documents the CustomUserMessageAuthenticationException that
authenticate() already throws; its absence made PHPStan read the tests'
catch blocks as dead.
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (867706f) to head (34e22b3).

Additional details and impacted files
@@             Coverage Diff             @@
##             develop       #53   +/-   ##
===========================================
  Coverage     100.00%   100.00%           
  Complexity        62        62           
===========================================
  Files              9         9           
  Lines            282       282           
===========================================
  Hits             282       282           
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

2 participants