diff --git a/src/Watchers/JobWatcher.php b/src/Watchers/JobWatcher.php index 8580af228..b6d05063c 100644 --- a/src/Watchers/JobWatcher.php +++ b/src/Watchers/JobWatcher.php @@ -4,6 +4,7 @@ use Illuminate\Bus\BatchRepository; use Illuminate\Contracts\Encryption\Encrypter; +use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Queue\Events\JobFailed; use Illuminate\Queue\Events\JobProcessed; use Illuminate\Queue\Queue; @@ -266,7 +267,7 @@ protected function getBatchId(array $data) $properties = ExtractProperties::from($command); return $properties['batchId'] ?? null; - } catch (\Exception|\Error) { + } catch (ModelNotFoundException $e) { if (preg_match('/"batchId";s:\d+:"([^"]+)"/', $data['command'], $matches)) { return $matches[1]; } diff --git a/tests/Watchers/JobWatcherTest.php b/tests/Watchers/JobWatcherTest.php index 570929f8f..6a8e68dd0 100644 --- a/tests/Watchers/JobWatcherTest.php +++ b/tests/Watchers/JobWatcherTest.php @@ -7,14 +7,17 @@ use Illuminate\Contracts\Debug\ExceptionHandler; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Database\Schema\Blueprint; +use Illuminate\Foundation\Auth\User; use Illuminate\Queue\Jobs\Job; use Illuminate\Queue\QueueManager; +use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\Schema; use Illuminate\Support\Str; use Laravel\Telescope\EntryType; use Laravel\Telescope\Tests\FeatureTestCase; use Laravel\Telescope\Watchers\JobWatcher; use Orchestra\Testbench\Attributes\WithMigration; +use Orchestra\Testbench\Factories\UserFactory; use Throwable; #[WithMigration('queue')] @@ -124,6 +127,30 @@ public function test_it_handles_pushed_jobs() $this->assertSame('default', $entry->content['queue']); $this->assertSame(['framework' => 'Laravel'], $entry->content['data']); } + + public function test_job_can_handle_deleted_serialized_model() + { + $user = UserFactory::new()->create(); + + $this->app->get(Dispatcher::class)->dispatch( + new MockedDeleteUserJob($user) + ); + + $this->artisan('queue:work', [ + 'connection' => 'database', + '--once' => true, + ])->run(); + + $entry = $this->loadTelescopeEntries()->first(); + + $this->assertSame(EntryType::JOB, $entry->type); + $this->assertSame('processed', $entry->content['status']); + $this->assertSame('database', $entry->content['connection']); + $this->assertSame(MockedDeleteUserJob::class, $entry->content['name']); + $this->assertSame('default', $entry->content['queue']); + + $this->assertSame(sprintf('%s:%s', get_class($user), $user->getKey()), $entry->content['data']['user']); + } } class MockedBatchableJob implements ShouldQueue @@ -145,6 +172,27 @@ public function handle() } } +class MockedDeleteUserJob implements ShouldQueue +{ + use SerializesModels; + + public $connection = 'database'; + + public $deleteWhenMissingModels = true; + + public $user; + + public function __construct(User $user) + { + $this->user = $user; + } + + public function handle() + { + $this->user->delete(); + } +} + class MyDatabaseJob implements ShouldQueue { public $connection = 'database';