Closed
Description
- Laravel Version:9.17.0
- PHP Version: 8.1.7
Description:
The catch
callback attached to a chain of jobs is called more than once when using the sync
connection. I expected the catch callback to only be called once. It's only called once for the redis and sqs queue connection. This is best illustrated as an example.
Bus::chain([
new TestJob(1),
new TestJob(2),
new TestJob(3),
new TestJob(4, exception: true),
new TestJob(5),
new TestJob(6),
new TestJob(7),
])->catch(function (Throwable $e): void {
dump('A job within the chain has failed...');
})->onConnection('sync')->dispatch();
The above chain will call catch 4 times.
"A job within the chain has failed..."
"A job within the chain has failed..."
"A job within the chain has failed..."
"A job within the chain has failed..."
Exception
foobar 4
The further down the exception the more times catch will be called for example if the exception at index 4 catch will be called 5 times, if it's at index 5 it will be called 6 times, etc.
Steps To Reproduce:
Here is an isolated console command to test it:
<?php
declare(strict_types=1);
namespace App\Console\Commands;
use Illuminate\Bus\Queueable;
use Illuminate\Console\Command;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Bus;
final class TestJob implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
public function __construct(protected int $id, protected bool $exception = false)
{
}
public function handle(): void
{
dump(__METHOD__." {$this->id}");
if ($this->exception) {
throw new \Exception("foobar {$this->id}");
}
}
}
final class TestChainCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'sandbox:chain';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Test chained job exceptions';
/**
* Execute the console command.
*/
public function handle(): int
{
Bus::chain([
new TestJob(1),
new TestJob(2),
new TestJob(3),
new TestJob(4, exception: true),
new TestJob(5),
new TestJob(6),
new TestJob(7),
])->catch(function (\Throwable $e): void {
dump('A job within the chain has failed...');
})->onConnection('sync')->dispatch();
return 0;
}
}