admin管理员组

文章数量:1417718

Throughout the process of upgrading Laravel 10 -> 11, statamic/cms was also upgraded from 4 -> 5. Since this occurred i've noticed some service providers not booting when the app is bootstrapping only before calls to Kernel files.

For context, the package ylsideas/feature-flags adds a macro to the Event facade for skipWithoutFeature for use in the kernel schedule which was not loaded at the point of the kernel. Tracing through vendor files led me to the vendor/laravel/framework/src/Illuminate/Foundation/Application::boot method.

When the app is bootstrapping it walks through all service providers and boots them to be accessible. This halts on statamic/cms/src/Providers/AppServiceProvider.php on the line:

$this->app->make(Schedule::class)->job(new HandleEntrySchedule)->everyMinute()

No exception or throwable is thrown from this line, by catching in a try/catch, but additionally no code execution is performed afterwards which causes further service providers to not be booted. This issue does not persist after the kernel is registered and the macro is then applied.

What could this issue be, and how is it possible to debug when no catchable exception is thrown and no logs produced?

Throughout the process of upgrading Laravel 10 -> 11, statamic/cms was also upgraded from 4 -> 5. Since this occurred i've noticed some service providers not booting when the app is bootstrapping only before calls to Kernel files.

For context, the package ylsideas/feature-flags adds a macro to the Event facade for skipWithoutFeature for use in the kernel schedule which was not loaded at the point of the kernel. Tracing through vendor files led me to the vendor/laravel/framework/src/Illuminate/Foundation/Application::boot method.

When the app is bootstrapping it walks through all service providers and boots them to be accessible. This halts on statamic/cms/src/Providers/AppServiceProvider.php on the line:

$this->app->make(Schedule::class)->job(new HandleEntrySchedule)->everyMinute()

No exception or throwable is thrown from this line, by catching in a try/catch, but additionally no code execution is performed afterwards which causes further service providers to not be booted. This issue does not persist after the kernel is registered and the macro is then applied.

What could this issue be, and how is it possible to debug when no catchable exception is thrown and no logs produced?

Share Improve this question asked Jan 31 at 9:30 Matthew BradleyMatthew Bradley 7573 silver badges15 bronze badges 5
  • What did you upgrade first? When did it break first? Have you tried reverting? Does it still works? – hakre Commented Jan 31 at 11:01
  • 1 Have you tried using a step-debugger? (it's not entirely clear from your question). Split the line over multiple lines to identify the actual place where it stops. Use variable assignments to do that. (if you don't have a step debugger at hand, which I would recommend first of all for such problems). – hakre Commented Jan 31 at 11:03
  • And given ->everyMinute() just out of the blue, this perhaps halts for one minute. If you temporarily increase the timeout to 180 seconds of PHP/Webserver, this could also a way to check for that. But then again, I'd recommend a step debugger. – hakre Commented Jan 31 at 11:06
  • Some good tips here which led to me debugging this. The issue was that the call to make the Schedule class threw an exception because, when resolving, that file contained use of macros provided in a later service provider. The fix for this would be to re-order these service providers when bootstrapping to ensure the macro is available. When I figure that out, i'll answer this question unless there is another answer providing that. – Matthew Bradley Commented Jan 31 at 11:32
  • Add that as an answer, there belongs the information. And yes, that's perfectly fine, see stackoverflow/help/self-answer – hakre Commented Jan 31 at 11:42
Add a comment  | 

1 Answer 1

Reset to default 0

This was caused by a conflict of bootstrapping order between two packages.

The vendor/statamic/cms/src/Providers/AppServiceProvider.php provider will run first, appending a task to the vendor/laravel/framework/src/Illuminate/Console/Scheduling/Schedule.php class.

The vendor/ylsideas/feature-flags/src/FeatureFlagsServiceProvider.php provider runs second and applies a macro for use within app/Console/Kernel.php.

When the macro is used, because the FeatureFlagsServiceProvider has not yet been booted, the call to $this->app->make(Schedule::class) will throw an exception and therefore stop further service providers from being booted.

To fix this issue, within the app/Providers/AppServiceProvider::register method I manually boot this service provider first:

$this->app->booting(function(Application $app) {
    $app->make(FeatureFlagsServiceProvider::class, ['app' => $app])->boot();
});

This then makes the macro available to the facade, preventing any issues in the initial service provider.

本文标签: phpStatamic AppServiceProvider halting app bootstrappingStack Overflow