Skip to content

Exception enhancements - #61791

Merged
taylorotwell merged 5 commits into
laravel:13.xfrom
timacdonald:exceptions
Sep 30, 2026
Merged

taylorotwell merged 5 commits into
laravel:13.xfrom
timacdonald:exceptions

Conversation

@timacdonald

@timacdonald timacdonald commented Sep 30, 2026 •

Copy link
Copy Markdown
Member
  • Improved Octane support (execution timestamp)
  • Additional tests to ensure we don't leak user ID from Context in places I'm paranoid about
  • Little bit of refactoring for better encapsulation

@github-actions

Copy link
Copy Markdown

Thanks for submitting a PR!

Note that draft PRs are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface.

Pull requests that are abandoned in draft may be closed due to inactivity.

@timacdonald
timacdonald marked this pull request as ready for review September 30, 2026 03:33
@taylorotwell
taylorotwell merged commit f6bcad9 into laravel:13.x Sep 30, 2026
60 checks passed
timacdonald added a commit to timacdonald/framework that referenced this pull request Oct 20, 2026
* Collapses into single listener

* Additional tests

* Capture correct execution time for Octane

* Introduce dehydration hook

* use class directly

(cherry picked from commit f6bcad9)
timacdonald added a commit to timacdonald/framework that referenced this pull request Oct 20, 2026
* Collapses into single listener

* Additional tests

* Capture correct execution time for Octane

* Introduce dehydration hook

* use class directly

(cherry picked from commit f6bcad9)
timacdonald added a commit to timacdonald/framework that referenced this pull request Oct 20, 2026
timacdonald added a commit to timacdonald/framework that referenced this pull request Oct 20, 2026
taylorotwell added a commit that referenced this pull request Oct 21, 2026
* [13.x] Introduce a Cloud facade (#61275)

Backported as the rename only, without the facade and CloudManager.

* cloud facade

Update CloudManager.php

dont need this import after alll

Rename Cloud foundation to bootstrapper

holy pr feedback

facade bits

test

clean method names

* Update CloudBootstrapperTest.php

* cs

(cherry picked from commit 5fbd12d)
(cherry picked from commit 4029930)

* [13.x] Cloud enhancements (#61360)

* Improve testing story

* Return if event writing was successful

* Return whether job was successfully forgotten or not

* Register cloud events earlier

* Make Stan happy

* Update tests

* Improve doc blocks

* Update CloudBootstrapper.php

---------

Co-authored-by: Taylor Otwell <taylor@laravel.com>
(cherry picked from commit cb7494d)
(cherry picked from commit 1498177)

* Allow retrieving command by name without resolving all commands (#61361)

(cherry picked from commit ca0e114)
(cherry picked from commit 2a41a03)

* rename to find command

(cherry picked from commit 2795df5)
(cherry picked from commit 027b3db)

* [13.x] Expose methods (#61362)

* Expose methods publicly

* formatting

---------

Co-authored-by: Taylor Otwell <taylor@laravel.com>
(cherry picked from commit 48ac5b8)
(cherry picked from commit 8ab250f)

* [13.x] Cloud exceptions (#61704)

On 11.x, GuardHelpers::id() retrieves the user before reading its identifier, so the user-retrieval count expected by testItCapturesTheUserResolvedByLaravelsExceptionContext is one higher than on 12.x.

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Extract Cloud command UUID for use as exception trace

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Improve test names

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* formatting

* tweak user handling for octaned

* Propagate the request trace ID to jobs dispatched from requests

Jobs are meant to be reported under the trace of the execution that
dispatched them. The trace is carried to the job in hidden Context,
written by the ContextDehydrating listener when the job's payload is
created.

That listener was only registered for console processes, so jobs
dispatched from HTTP requests never carried a trace. Their exceptions
were reported with a null trace_id. Worse, when one of those jobs
dispatched another job, the worker filled the gap with its own
process-wide command trace, grouping every such child job handled by
the worker under a single, unrelated trace.

The listener is now registered for requests as well. When the Context
does not already hold a trace, it falls back to the Cloud-Request-ID
header in requests (the same value the request's own exception reports
use) and to the command trace in the console.

This mirrors what Nightwatch does on Laravel Cloud, where the request
trace is also the Cloud-Request-ID and is propagated to jobs through
hidden Context. Unlike Nightwatch, the trace is written lazily when a
job is dispatched rather than when the execution starts, since only
job payloads need it and the framework has no hook before middleware.
Requests without a Cloud-Request-ID continue to report no trace, and
their jobs now match them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: jradtilbrook <jarryd@tilbrooktech.com>
Co-authored-by: Taylor Otwell <taylor@laravel.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit fee86a4)
(cherry picked from commit 1df0544)

* Add mime type to the files reportable details (#61772)

(cherry picked from commit 1003c6e)
(cherry picked from commit 342e070)

* Update facade docblocks

* Improve exception reporting

* Exception enhancements (#61791)

* Collapses into single listener

* Additional tests

* Capture correct execution time for Octane

* Introduce dehydration hook

* use class directly

(cherry picked from commit f6bcad9)

---------

Co-authored-by: Jack Bayliss <jjbayliss@icloud.com>
Co-authored-by: Taylor Otwell <taylor@laravel.com>
Co-authored-by: jradtilbrook <jarryd@tilbrooktech.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Sabrina Bourouis <bourouis.sabrina@laposte.net>
taylorotwell pushed a commit that referenced this pull request Oct 22, 2026
* Add the Laravel Cloud events emitter

(cherry picked from commit af58899)

* Allow retrieving command by name without resolving all commands

(cherry picked from commit f6b63bd)

* Expose the exception context

(cherry picked from commit 67ec8c1)

* Reset the alias loader between tests

(cherry picked from commit 7604387)

* Report exceptions to Laravel Cloud

(cherry picked from commit 4a824b8)

* Improve exception reporting

(cherry picked from commit 0641580)

* Remove files accidentally added by the cherry-pick

(cherry picked from commit 6a23f78)

* Skip the command constructor test on Symfony Console versions that discard the exception.

(cherry picked from commit 8f564da)

* [12.x] Fix `Request::getAcceptableContentTypes()` changes in Symfony 7.4 (#57783) (#57806)

* [12.x] Fix `Request::getAcceptableContentTypes()` changes in Symfony 7.4

Symfony 7.4 changes the return value of `getAcceptableContentType()` to
include additional value after `;`. E,g: `application/json; charset=utf-8` returns `application/json` in 7.3 and
below while 7.4 return the full value.

* wip

---------

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>
Co-authored-by: Mior Muhammad Zaki <crynobone@gmail.com>
(cherry picked from commit 3b3c9f9)

* Adapt Cloud exception reporting to Laravel 9 and PHP 8.0.

* Fix the source static analysis on Laravel 9.

* Update type assertions for the current PHPStan release.

* Update the CI workflows to supported runners and actions.

* Expect quoted queue worker options on Windows with Symfony Process 6.4.33 and newer.

(cherry picked from commit 70e09eb)

* Create the queue tables for the Cloud exception tests without newer Testbench helpers.

* Reset the test clock after the wormhole tests.

* Allow PHP 8.0 CI jobs to install packages with security advisories.

* Allow reading protected members through reflection on PHP 8.0.

* Suppress the AWS SDK PHP 8.0 deprecation warning in CI.

* Avoid AWS SDK and PSR-7 combinations that raise deprecations in CI.

* Use a range without shell operators for the PHP 8.0 PSR-7 constraint.

* Report the time Octane received the request, ported from #61791.

(cherry picked from commit ff66be4)

* Allow running Artisan without a command name when reporting exceptions to Cloud.

* Test that the exceptions config is stored after configuration is loaded.

(cherry picked from commit 9e94433)

* Map compiled views back to their Blade source in reported exceptions.

(cherry picked from commit cc43bf5)

* Allow the Blade mapper to read the compiler engine's protected state on PHP 8.0.

* Resolve the Blade mapper for each reported view exception.

(cherry picked from commit 5ccdd3b)

* Rename the Cloud bootstrapper to CloudBootstrapper to match 13.x.

* Match the registration spacing of 13.x.

* Keep the redact_command_input_fields default for parity with 13.x.

* Keep the reporter's console input and queue normalisation in step with 13.x.

* Keep the console command line, Laravel context and context lookups in step with 13.x.

* Order the bootstrapper import after the Cloud namespace imports.

* Keep the constructor docblock convention of the branch.

* Rename forgetLoggedOutUser to forgetUser.

* Capture only the trace and user identifiers from the job payload.

* Read the trace and user identifiers from the current job's payload on demand.

* Inline the job payload lookups.

* Keep the 13.x docblock on the user context lookup.

* Remove the @return docblock from the Blade mapper constructor.

* Forget the user that logged out when Octane receives the next request.

* Resolve the Blade mapper through a resolver closure.

(cherry picked from commit 058631e)

---------

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>
Co-authored-by: Graham Campbell <GrahamCampbell@users.noreply.github.com>
Co-authored-by: Mior Muhammad Zaki <crynobone@gmail.com>
taylorotwell pushed a commit that referenced this pull request Oct 24, 2026
* Add the Laravel Cloud events emitter

* Allow retrieving command by name without resolving all commands

* Expose the exception context

* Reset the alias loader between tests

* Report exceptions to Laravel Cloud

* Improve exception reporting

* Remove files accidentally added by the cherry-pick

* Skip the command constructor test on Symfony Console versions that discard the exception.

* [12.x] Fix `Request::getAcceptableContentTypes()` changes in Symfony 7.4 (#57783) (#57806)

* [12.x] Fix `Request::getAcceptableContentTypes()` changes in Symfony 7.4

Symfony 7.4 changes the return value of `getAcceptableContentType()` to
include additional value after `;`. E,g: `application/json; charset=utf-8` returns `application/json` in 7.3 and
below while 7.4 return the full value.

* wip

---------

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>
Co-authored-by: Mior Muhammad Zaki <crynobone@gmail.com>
(cherry picked from commit 3b3c9f9)

* Expect quoted queue worker options on Windows with Symfony Process 6.4.33 and newer.

* Run the SQL Server tests on a supported runner.

* Report the time Octane received the request, ported from #61791.

* Test that the exceptions config is stored after configuration is loaded.

* Map compiled views back to their Blade source in reported exceptions.

* Resolve the Blade mapper for each reported view exception.

(cherry picked from commit 5ccdd3b)

* Rename the Cloud bootstrapper to CloudBootstrapper to match 13.x.

* Match the registration spacing of 13.x.

* Keep the redact_command_input_fields default for parity with 13.x.

* Keep the reporter's console input and queue normalisation in step with 13.x.

* Keep the console command line, Laravel context and context lookups in step with 13.x.

* Order the bootstrapper import after the Cloud namespace imports.

* Keep the constructor docblock convention of the branch.

* Rename forgetLoggedOutUser to forgetUser.

* Capture only the trace and user identifiers from the job payload.

* Read the trace and user identifiers from the current job's payload on demand.

* Inline the job payload lookups.

* Keep the 13.x docblock on the user context lookup.

* Remove the @return docblock from the Blade mapper constructor.

* Forget the user that logged out when Octane receives the next request.

* Resolve the Blade mapper through a resolver closure.

(cherry picked from commit 058631e)

---------

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>
Co-authored-by: Graham Campbell <GrahamCampbell@users.noreply.github.com>
Co-authored-by: Mior Muhammad Zaki <crynobone@gmail.com>
taylorotwell added a commit that referenced this pull request Oct 24, 2026
* [13.x] Introduce a Cloud facade (#61275)

Backported as the rename only, without the facade and CloudManager.

* cloud facade

Update CloudManager.php

dont need this import after alll

Rename Cloud foundation to bootstrapper

holy pr feedback

facade bits

test

clean method names

* Update CloudBootstrapperTest.php

* cs

(cherry picked from commit 5fbd12d)

* [13.x] Cloud enhancements (#61360)

* Improve testing story

* Return if event writing was successful

* Return whether job was successfully forgotten or not

* Register cloud events earlier

* Make Stan happy

* Update tests

* Improve doc blocks

* Update CloudBootstrapper.php

---------

Co-authored-by: Taylor Otwell <taylor@laravel.com>
(cherry picked from commit cb7494d)

* Allow retrieving command by name without resolving all commands (#61361)

(cherry picked from commit ca0e114)

* rename to find command

(cherry picked from commit 2795df5)

* [13.x] Expose methods (#61362)

* Expose methods publicly

* formatting

---------

Co-authored-by: Taylor Otwell <taylor@laravel.com>
(cherry picked from commit 48ac5b8)

* [13.x] Cloud exceptions (#61704)

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Extract Cloud command UUID for use as exception trace

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Improve test names

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* formatting

* tweak user handling for octaned

* Propagate the request trace ID to jobs dispatched from requests

Jobs are meant to be reported under the trace of the execution that
dispatched them. The trace is carried to the job in hidden Context,
written by the ContextDehydrating listener when the job's payload is
created.

That listener was only registered for console processes, so jobs
dispatched from HTTP requests never carried a trace. Their exceptions
were reported with a null trace_id. Worse, when one of those jobs
dispatched another job, the worker filled the gap with its own
process-wide command trace, grouping every such child job handled by
the worker under a single, unrelated trace.

The listener is now registered for requests as well. When the Context
does not already hold a trace, it falls back to the Cloud-Request-ID
header in requests (the same value the request's own exception reports
use) and to the command trace in the console.

This mirrors what Nightwatch does on Laravel Cloud, where the request
trace is also the Cloud-Request-ID and is propagated to jobs through
hidden Context. Unlike Nightwatch, the trace is written lazily when a
job is dispatched rather than when the execution starts, since only
job payloads need it and the framework has no hook before middleware.
Requests without a Cloud-Request-ID continue to report no trace, and
their jobs now match them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: jradtilbrook <jarryd@tilbrooktech.com>
Co-authored-by: Taylor Otwell <taylor@laravel.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit fee86a4)

* Add mime type to the files reportable details (#61772)

(cherry picked from commit 1003c6e)

* Update facade docblocks

* Improve exception reporting

* Exception enhancements (#61791)

* Collapses into single listener

* Additional tests

* Capture correct execution time for Octane

* Introduce dehydration hook

* use class directly

(cherry picked from commit f6bcad9)

* Resolve the Blade mapper for each reported view exception.

(cherry picked from commit 5ccdd3b)

* Match the registration spacing of 13.x.

* Add missing @throws \JsonException annotations (#60514)

(cherry picked from commit a6ce2a7)

* Foundation\Cloud\Events: remove an unused import and fix docblock (#60378)

(cherry picked from commit 7433202)

* Resolve the Blade mapper through a resolver closure.

(cherry picked from commit 058631e)

---------

Co-authored-by: Jack Bayliss <jjbayliss@icloud.com>
Co-authored-by: Taylor Otwell <taylor@laravel.com>
Co-authored-by: jradtilbrook <jarryd@tilbrooktech.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Sabrina Bourouis <bourouis.sabrina@laposte.net>
@timacdonald
timacdonald deleted the exceptions branch October 26, 2026 03:29
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