diff --git a/src/Illuminate/Bus/PendingBatch.php b/src/Illuminate/Bus/PendingBatch.php index ba130fcefd1d..53057750171a 100644 --- a/src/Illuminate/Bus/PendingBatch.php +++ b/src/Illuminate/Bus/PendingBatch.php @@ -47,6 +47,13 @@ class PendingBatch */ public $options = []; + /** + * Jobs that have been verified to contain the Batchable trait. + * + * @var array + */ + protected static $batchableClasses = []; + /** * Create a new pending batch instance. * @@ -92,14 +99,16 @@ protected function ensureJobIsBatchable(object|array $job): void { foreach (Arr::wrap($job) as $job) { if ($job instanceof PendingBatch) { - $this->ensureJobIsBatchable($job->jobs->all()); - return; } - if (! in_array(Batchable::class, class_uses_recursive($job))) { + if (! (static::$batchableClasses[$job::class] ?? false) && ! in_array(Batchable::class, class_uses_recursive($job))) { + static::$batchableClasses[$job::class] = false; + throw new RuntimeException(sprintf('Attempted to batch job [%s], but it does not use the Batchable trait.', $job::class)); } + + static::$batchableClasses[$job::class] = true; } } diff --git a/tests/Bus/BusPendingBatchTest.php b/tests/Bus/BusPendingBatchTest.php index d0398da85e69..6b375daffac7 100644 --- a/tests/Bus/BusPendingBatchTest.php +++ b/tests/Bus/BusPendingBatchTest.php @@ -231,4 +231,22 @@ public function test_it_throws_exception_if_batched_job_is_not_batchable(): void new PendingBatch(new Container, new Collection([$nonBatchableJob])); } + + public function test_it_throws_an_exception_if_batched_job_contains_batch_with_nonbatchable_job(): void + { + $this->expectException(RuntimeException::class); + + $container = new Container; + new PendingBatch( + $container, + new Collection( + [new PendingBatch($container, new Collection([new BatchableJob, new class {}]))] + ) + ); + } +} + +class BatchableJob +{ + use Batchable; }