Skip to content

queue:retry is broken after recent commit #35825

@chaoszcat

Description

@chaoszcat
  • Laravel Version: 8.21.0
  • PHP Version: 8.0.0
  • Database Driver & Version: MySQL

Description:

A recent pull on the framework has broken the php artisan queue:retry. I submitted a comment on the commit but decided to create this issue since this is reproducible.

Steps To Reproduce:

  1. Create a fresh project
composer create-project laravel/laravel test
  1. Create database migrations
php artisan queue:table
php artisan migrate
  1. Insert a new user into the users table with an email address.
INSERT INTO users SET name="test", email="[email protected]", password="";
  1. Make sure .env is using database as the queue driver:
QUEUE_CONNECTION=database
  1. Create a new notification that will fail (app/Notifications/TestNotification.php)
<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;

class TestNotification extends Notification implements ShouldQueue
{
    use Queueable;
    
    public function via($notifiable)
    {
        return ['mail'];
    }

    public function toMail($notifiable)
    {
        throw new \RuntimeException('Purposely fail this notification to test queue:retry');
    }
}
  1. Insert the notification into queue by calling this anywhere from the code:
(\App\Models\User::find(1))->notify(new \App\Notifications\TestNotification());
  1. Run the queue worker. The worker should fail.
php artisan queue:work
  1. Retry the queue, and the problem arise:
php artisan queue:retry all
ErrorException 

Attempt to read property "timestamp" on null

  at vendor/laravel/framework/src/Illuminate/Queue/Console/RetryCommand.php:132
    128▕ 
    129▕         $instance = unserialize($payload['data']['command']);
    130▕ 
    131▕         if (is_object($instance) && method_exists($instance, 'retryUntil')) {
  ➜ 132▕             $payload['retryUntil'] = $instance->retryUntil()->timestamp;
    133▕         }
    134▕ 
    135▕         return json_encode($payload);
    136▕     }

      +16 vendor frames 

Reasoning:

As per my comment on the commit, the retryUntil() method in the class SendQueuedNotifications does not always return a Carbon object as expected in the RetryCommand. Suggest a fix is to check also if the retryUntil() is returning a Carbon object before accessing the timestamp field.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions