-
Notifications
You must be signed in to change notification settings - Fork 11.6k
Description
- Laravel Version: 5.5.33
- PHP Version: 7.0.27
- Database Driver & Version: MySQL 5.5
Description:
Because the application was recently upgraded to Laravel 5.5, I haven't had time to switch to FETCH_OBJ. I had to use the FETCH_ASSOC for compatibility until I get the time to rewrite a few hundred lines of code.
The job queue cannot be retried because:
In RetryCommand.php line 70:
[ErrorException]
Trying to get property of non-object
Steps To Reproduce:
You must switch the PDOStatement fetch mode to FETCH_ASSOC.
// From App\EventServiceProvider::boot
Event::listen(\Illuminate\Database\Events\StatementPrepared::class, function ($event) {
$event->statement->setFetchMode(\PDO::FETCH_ASSOC);
});
Architect a job that purposefully throws an exception, and queue it.
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class TestFailureJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
throw new \RuntimeException("This job is meant to fail.");
}
}
I queue it via php artisan tinker
, myself:
~/path/to/project $ artisan tinker
Psy Shell v0.8.17 (PHP 7.0.27 — cli) by Justin Hileman
>>> \App\Jobs\TestFailureJob::dispatch()->delay(now()->addSeconds(10))
=> Illuminate\Foundation\Bus\PendingDispatch {#1055}
Run the job so it lands in the failed_jobs
table, and then retry it...
php artisan queue:work --tries=1
php artisan queue:retry all
💥 💥 💥
In RetryCommand.php line 70:
[ErrorException]
Trying to get property of non-object
Mitigation
Here's how I'm mitigating the issue: by checking if the failed_jobs
or jobs
tables are being selected from.
Event::listen(\Illuminate\Database\Events\StatementPrepared::class, function ($event) {
/** @var \PDOStatement $stmt */
$stmt = $event->statement;
if (!preg_match('/ FROM `?(failed_jobs|jobs)`?/i', $stmt->queryString)) {
$stmt->setFetchMode(\PDO::FETCH_ASSOC);
}
});
Long-term, a patch to fix the RetryCommand would be better than this regex test. I thought I saw something about this on laravel/internals a little while ago, but I can't find it now.