Skip to content

Pre-release 4.2.123 → 4.2.122 — task 4.5 (foundation): the Exception package folds into Foundation's v13-shaped Handler - #96

Merged
agissept merged 1 commit into
masterfrom
pre-release/4.2.123
Oct 6, 2026
Merged

agissept merged 1 commit into
masterfrom
pre-release/4.2.123

Conversation

@oonid

@oonid oonid commented Oct 1, 2026 •

Copy link
Copy Markdown

Task 4.5, foundation — the Exception package folds into Foundation as v13's Handler

Stacks on #95. This is the third foundation slice. illuminate/exception leaves the replace block, so illuminate/foundation is the only package left for the flip. The handler takes v13's name and shape. When it renders a fallback page, it uses the app's errors.* views, as v13 does, not a displayer the app binds.

Changes

  • Illuminate\Exception\Handler becomes Illuminate\Foundation\Exceptions\Handler, v13's name, and implements v13's ExceptionHandler contract (report, shouldReport, render, renderForConsole).

    • Its constructor takes only the container, as v13's does.
    • Debug mode is read from app.debug when an exception is displayed, so setDebug() and the displayer constructor arguments are gone.
  • Fallback page. When no render callback answers, the handler renders the app's errors.{status} view, then errors.{N}xx, as v13 does. It passes the status and headers of an HttpExceptionInterface. If neither view exists, or rendering it fails, it shows the plain page. The debug displayer (Whoops) still renders in debug mode and in the console.

  • An error raised while handling an error is reported through the same report callbacks before the fallback renders. v13 reports such an error through the handler too: it reaches the HTTP Kernel, which reports it. Until now the app's displayer reported it on its own.

  • Moves:

    • The displayers move to Foundation\Exceptions\Displayers and the provider to Foundation\Providers. The provider always binds exception.plain to the plain displayer; the console case moved into the handler.
    • ExceptionHandlerAdapter is removed: the queue worker's ExceptionHandler binding now resolves the handler itself.
    • src/Illuminate/Exception/composer.json is removed.
  • Tests move to tests/Foundation/Exceptions/. HandlerTest adds cases for:

    • the v13 contract;
    • the error view by status and by Nxx, with its headers;
    • the plain fallback when the view is missing or throws;
    • the second error being reported;
    • the console using the debug displayer;
    • debug mode read from config;
    • renderForConsole().

    QueueForkBridgeTest checks that the worker's bound contract is the handler.

Verification

  • Fork: the suite is 280 green on PHPUnit 11.5.56. The ratchet is green, with every pattern at its baseline.
  • The tests catch real breaks. Each of these 7 mutations fails at least one test:
    • not reporting the second error;
    • not special-casing the console;
    • not trying the Nxx view;
    • trying Nxx before the status view;
    • not catching a failing view;
    • dropping the HTTP headers;
    • never reading debug mode.
  • Downstream: the dicoding app pair is dicoding-dev/dicoding#6000 (feature/platform/framework-4.2.123-rc1). It drops its own ExceptionServiceProvider and FiveZeroZeroDisplayer and adds errors/5xx and errors/4xx views that show its branded error page. It ran with vendor installed exactly from its lock:
    • Psalm (full project, no cache): no errors.
    • Unit suite: 8962 green.
    • Integration suite: all 3023 tests, including a new one for an error raised while rendering. The only failures are the 4 long-standing ones and one timing-sensitive test, which fails whenever its check runs in a later second than the record it checks was created. 196 are skipped, and no test is flagged risky.
    • The real entry points (php -S + server.php → index.php, and 7 artisan commands) and the 13 in-process request scenarios are identical to 4.2.122.
    • The fallback, through php -S: a route's exception throws from its own render(). Every status and page body is byte-identical to 4.2.122. The render failure is now logged at ERROR through the app's report callbacks; before, the app's displayer logged it at ALERT.
  • Checks ran in a cloud container without deck (PHP 8.4.26, MariaDB 10.11).

Tag

4.2.123 (7ae0eb9f) is not pushed, and neither are 4.2.119–4.2.122. Tag pushes are refused for this session.

🤖 Generated with Claude Code

https://claude.ai/code/session_0169SsatCE8LhaTsQTPiGtVo

@agissept
agissept force-pushed the pre-release/4.2.123 branch from 7ae0eb9 to 8818f9c Compare October 2, 2026 09:20
@agissept
agissept added this pull request to stack #102 October 5, 2026 06:14
@agissept
agissept force-pushed the pre-release/4.2.123 branch 3 times, most recently from c95e635 to 563bde6 Compare October 5, 2026 08:40
Base automatically changed from pre-release/4.2.122 to master October 6, 2026 02:35
…3-shaped Handler (task 4.5)

illuminate/exception leaves the replace block; only illuminate/foundation
remains for the flip.

- Illuminate\Exception\Handler becomes Illuminate\Foundation\Exceptions\Handler,
  v13's name, and implements v13's ExceptionHandler contract
  (report/shouldReport/render/renderForConsole). Its constructor takes only the
  container, as v13's does, and debug mode is read from app.debug when an
  exception is displayed.
- When no render callback answers, it renders the app's errors.{status} or
  errors.{N}xx view, as v13 does, and the plain page when there is none or it
  fails. The debug displayer (Whoops) still renders in debug mode and in the
  console.
- An error raised while handling an error is reported through the same
  report callbacks before the fallback renders, as v13's HandleExceptions does.
- The displayers move to Foundation\Exceptions\Displayers and the provider to
  Foundation\Providers. ExceptionHandlerAdapter goes: the queue worker's
  ExceptionHandler binding now resolves the handler itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0169SsatCE8LhaTsQTPiGtVo
@agissept
agissept force-pushed the pre-release/4.2.123 branch from 563bde6 to 19007aa Compare October 6, 2026 02:35
@agissept
agissept marked this pull request as ready for review October 6, 2026 02:36
@agissept
agissept merged commit 9bba9e0 into master Oct 6, 2026
2 checks passed
@agissept
agissept deleted the pre-release/4.2.123 branch October 6, 2026 02:36
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.

3 participants