Skip to content

The catch callback attached to a chain of jobs is called more than once #42883

Closed
@gerardroche

Description

@gerardroche
  • 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;
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions