Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

queue:retry is broken after recent commit #35825

Closed
chaoszcat opened this issue Jan 8, 2021 · 4 comments · Fixed by #35828
Closed

queue:retry is broken after recent commit #35825

chaoszcat opened this issue Jan 8, 2021 · 4 comments · Fixed by #35828
Labels

Comments

@chaoszcat
Copy link

chaoszcat commented Jan 8, 2021

  • 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="test@example.com", 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.

chaoszcat referenced this issue in illuminate/queue Jan 8, 2021
@rodrigopedra
Copy link
Contributor

I guess this is fixed by this commit: 4415b94

But it still needs to be tagged.

@chaoszcat
Copy link
Author

@rodrigopedra no it's not. The if case in RetryCommand is checking if SendQueuedNotifications is indeed an object, and if the method retryUntil() is exist or not, and he simply call retryUntil()->timestamp without checking if the method is returning a Carbon object or not. The method defined in SendQueuedNotifications is returning null when the notification does not define a retryUntil().

@rodrigopedra
Copy link
Contributor

I see now, thanks for the heads up.

@driesvints
Copy link
Member

Thanks for the report. I've sent in a fix here: #35828

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants