Skip to content

Commit b0cb237

Browse files
[12.x] Set job instance on "failed" command instance (#55617)
* Add failing test * Update test to expect the new argument * Set the job instance when creating a new instance of command after failure * Update CallQueuedHandler.php --------- Co-authored-by: Taylor Otwell <[email protected]>
1 parent c895e4d commit b0cb237

File tree

4 files changed

+48
-3
lines changed

4 files changed

+48
-3
lines changed

src/Illuminate/Queue/CallQueuedHandler.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,12 +274,17 @@ protected function ensureUniqueJobLockIsReleasedViaContext()
274274
* @param array $data
275275
* @param \Throwable|null $e
276276
* @param string $uuid
277+
* @param \Illuminate\Contracts\Queue\Job|null $job
277278
* @return void
278279
*/
279-
public function failed(array $data, $e, string $uuid)
280+
public function failed(array $data, $e, string $uuid, ?Job $job = null)
280281
{
281282
$command = $this->getCommand($data);
282283

284+
if (! is_null($job)) {
285+
$command = $this->setJobInstanceIfNecessary($job, $command);
286+
}
287+
283288
if (! $command instanceof ShouldBeUniqueUntilProcessing) {
284289
$this->ensureUniqueJobLockIsReleased($command);
285290
}

src/Illuminate/Queue/Jobs/Job.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ protected function failed($e)
251251
[$class, $method] = JobName::parse($payload['job']);
252252

253253
if (method_exists($this->instance = $this->resolve($class), 'failed')) {
254-
$this->instance->failed($payload['data'], $e, $payload['uuid'] ?? '');
254+
$this->instance->failed($payload['data'], $e, $payload['uuid'] ?? '', $this);
255255
}
256256
}
257257

tests/Queue/QueueBeanstalkdJobTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Illuminate\Contracts\Events\Dispatcher;
88
use Illuminate\Queue\Events\JobFailed;
99
use Illuminate\Queue\Jobs\BeanstalkdJob;
10+
use Illuminate\Queue\Jobs\Job;
1011
use Mockery as m;
1112
use Pheanstalk\Contract\JobIdInterface;
1213
use Pheanstalk\Contract\PheanstalkManagerInterface;
@@ -39,7 +40,7 @@ public function testFailProperlyCallsTheJobHandler()
3940
$job->getPheanstalkJob()->shouldReceive('getData')->andReturn(json_encode(['job' => 'foo', 'uuid' => 'test-uuid', 'data' => ['data']]));
4041
$job->getContainer()->shouldReceive('make')->once()->with('foo')->andReturn($handler = m::mock(BeanstalkdJobTestFailedTest::class));
4142
$job->getPheanstalk()->shouldReceive('delete')->once()->with($job->getPheanstalkJob())->andReturnSelf();
42-
$handler->shouldReceive('failed')->once()->with(['data'], m::type(Exception::class), 'test-uuid');
43+
$handler->shouldReceive('failed')->once()->with(['data'], m::type(Exception::class), 'test-uuid', m::type(Job::class));
4344
$job->getContainer()->shouldReceive('make')->once()->with(Dispatcher::class)->andReturn($events = m::mock(Dispatcher::class));
4445
$events->shouldReceive('dispatch')->once()->with(m::type(JobFailed::class))->andReturnNull();
4546

tests/Queue/QueueSyncQueueTest.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,28 @@ public function testFailedJobGetsHandledWhenAnExceptionIsThrown()
6161
Container::setInstance();
6262
}
6363

64+
public function testFailedJobHasAccessToJobInstance()
65+
{
66+
unset($_SERVER['__sync.failed']);
67+
68+
$sync = new SyncQueue;
69+
$container = new Container;
70+
$container->bind(\Illuminate\Contracts\Events\Dispatcher::class, \Illuminate\Events\Dispatcher::class);
71+
$container->bind(\Illuminate\Contracts\Bus\Dispatcher::class, \Illuminate\Bus\Dispatcher::class);
72+
$container->bind(\Illuminate\Contracts\Container\Container::class, \Illuminate\Container\Container::class);
73+
$sync->setContainer($container);
74+
75+
SyncQueue::createPayloadUsing(function ($connection, $queue, $payload) {
76+
return ['data' => ['extra' => 'extraValue']];
77+
});
78+
79+
try {
80+
$sync->push(new FailingSyncQueueJob());
81+
} catch (LogicException $e) {
82+
$this->assertSame('extraValue', $_SERVER['__sync.failed']);
83+
}
84+
}
85+
6486
public function testCreatesPayloadObject()
6587
{
6688
$sync = new SyncQueue;
@@ -177,6 +199,23 @@ public function failed()
177199
}
178200
}
179201

202+
class FailingSyncQueueJob implements ShouldQueue
203+
{
204+
use InteractsWithQueue;
205+
206+
public function handle()
207+
{
208+
throw new LogicException();
209+
}
210+
211+
public function failed()
212+
{
213+
$payload = $this->job->payload();
214+
215+
$_SERVER['__sync.failed'] = $payload['data']['extra'];
216+
}
217+
}
218+
180219
class SyncQueueJob implements ShouldQueue
181220
{
182221
use InteractsWithQueue;

0 commit comments

Comments
 (0)