fix(scheduler): accept ScheduledJobManager jobs queued before the upgrade

Jobs that v4.3.23 put in the queue have no type property. The promoted
constructor property had no default, so these jobs failed with "must not
be accessed before initialization" after the upgrade.

- Declare type as a normal property with a null default
This commit is contained in:
Andras Bacsai
2026-10-05 21:18:48 +02:00
parent 2361161487
commit 13db52f730
2 changed files with 27 additions and 1 deletions
+9 -1
View File
@@ -64,15 +64,23 @@ class ScheduledJobManager implements ShouldQueue
private int $skippedCount = 0;
/**
* One key of TYPES, or null for all types.
*
* Declared with a default instead of promoted, so jobs queued by older versions without this property still run.
*/
public ?string $type = null;
/**
* @param string|null $type One key of TYPES, or null for all types.
*/
public function __construct(public ?string $type = null)
public function __construct(?string $type = null)
{
if ($type !== null && ! array_key_exists($type, self::TYPES)) {
throw new \InvalidArgumentException("Unknown scheduled job type [{$type}].");
}
$this->type = $type;
$this->onQueue(crons_queue());
}
@@ -0,0 +1,18 @@
<?php
use App\Jobs\ScheduledJobManager;
use Illuminate\Queue\Middleware\WithoutOverlapping;
use Tests\TestCase;
uses(TestCase::class);
it('uses the shared lock for a job queued before scheduled job types existed', function () {
// v4.3.23 serialized ScheduledJobManager without a type property.
$job = unserialize('O:'.strlen(ScheduledJobManager::class).':"'.ScheduledJobManager::class.'":0:{}');
$middleware = $job->middleware();
expect($job->type)->toBeNull()
->and($middleware[0])->toBeInstanceOf(WithoutOverlapping::class)
->and($middleware[0]->key)->toBe('scheduled-job-manager');
});