Skip to content

Commit

Permalink
[8.x] Prevent double throwing chained exception on sync queue (#42950)
Browse files Browse the repository at this point in the history
* prevent double throwing chained exception on sync queue

* decrease job count after processing
  • Loading branch information
rodrigopedra authored Jul 7, 2022
1 parent 33ef96e commit 41300c6
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 7 deletions.
20 changes: 17 additions & 3 deletions src/Illuminate/Queue/SyncQueue.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

class SyncQueue extends Queue implements QueueContract
{
protected $jobsCount = 0;

/**
* Get the size of the queue.
*
Expand All @@ -37,6 +39,8 @@ public function push($job, $data = '', $queue = null)
{
$queueJob = $this->resolveJob($this->createPayload($job, $queue, $data), $queue);

$this->jobsCount++;

try {
$this->raiseBeforeJobEvent($queueJob);

Expand All @@ -45,6 +49,8 @@ public function push($job, $data = '', $queue = null)
$this->raiseAfterJobEvent($queueJob);
} catch (Throwable $e) {
$this->handleException($queueJob, $e);
} finally {
$this->jobsCount--;
}

return 0;
Expand Down Expand Up @@ -113,11 +119,19 @@ protected function raiseExceptionOccurredJobEvent(Job $job, Throwable $e)
*/
protected function handleException(Job $queueJob, Throwable $e)
{
$this->raiseExceptionOccurredJobEvent($queueJob, $e);
static $isGuarded = false;

if ($isGuarded) {
$isGuarded = false;
} else {
$isGuarded = $this->jobsCount > 1;

$queueJob->fail($e);
$this->raiseExceptionOccurredJobEvent($queueJob, $e);

throw $e;
$queueJob->fail($e);

throw $e;
}
}

/**
Expand Down
54 changes: 50 additions & 4 deletions tests/Integration/Queue/JobChainingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

class JobChainingTest extends TestCase
{
public static $catchCallbackRan = false;
public static $catchCallbackCount = 0;

protected function getEnvironmentSetUp($app)
{
Expand All @@ -30,7 +30,6 @@ protected function tearDown(): void
JobChainingTestFirstJob::$ran = false;
JobChainingTestSecondJob::$ran = false;
JobChainingTestThirdJob::$ran = false;
static::$catchCallbackRan = false;
}

public function testJobsCanBeChainedOnSuccess()
Expand Down Expand Up @@ -148,19 +147,56 @@ public function testThirdJobIsNotFiredIfSecondFails()

public function testCatchCallbackIsCalledOnFailure()
{
self::$catchCallbackCount = 0;

Bus::chain([
new JobChainingTestFirstJob,
new JobChainingTestFailingJob,
new JobChainingTestSecondJob,
])->catch(static function () {
self::$catchCallbackRan = true;
self::$catchCallbackCount++;
})->dispatch();

$this->assertTrue(JobChainingTestFirstJob::$ran);
$this->assertTrue(static::$catchCallbackRan);
$this->assertSame(1, static::$catchCallbackCount);
$this->assertFalse(JobChainingTestSecondJob::$ran);
}

public function testCatchCallbackIsCalledOnceOnSyncQueue()
{
self::$catchCallbackCount = 0;

try {
Bus::chain([
new JobChainingTestFirstJob(),
new JobChainingTestThrowJob(),
new JobChainingTestSecondJob(),
])->catch(function () {
self::$catchCallbackCount++;
})->onConnection('sync')->dispatch();
} finally {
$this->assertTrue(JobChainingTestFirstJob::$ran);
$this->assertSame(1, static::$catchCallbackCount);
$this->assertFalse(JobChainingTestSecondJob::$ran);
}

self::$catchCallbackCount = 0;

try {
Bus::chain([
new JobChainingTestFirstJob(),
new JobChainingTestThrowJob(),
new JobChainingTestSecondJob(),
])->catch(function () {
self::$catchCallbackCount++;
})->onConnection('sync')->dispatch();
} finally {
$this->assertTrue(JobChainingTestFirstJob::$ran);
$this->assertSame(1, static::$catchCallbackCount);
$this->assertFalse(JobChainingTestSecondJob::$ran);
}
}

public function testChainJobsUseSameConfig()
{
JobChainingTestFirstJob::dispatch()->allOnQueue('some_queue')->allOnConnection('sync1')->chain([
Expand Down Expand Up @@ -293,3 +329,13 @@ public function handle()
$this->fail();
}
}

class JobChainingTestThrowJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable;

public function handle()
{
throw new \Exception();
}
}

0 comments on commit 41300c6

Please sign in to comment.