Laravel Horizon, retry a failed job only for specific error

208 views Asked by At

We're using horizon to run our queue and sending emails via mandrill. Occasionally mandrill will timeout and the email job fail. Simply rerunning it, it generally works fine but right now I am doing that manually via the horizon interface. I want to catch when it's a mandrill error and have it automatically rerun the job.

I can catch the error, running the job again is where I'm having trouble.

public function build()
{   
    throw new \Exception('This email is not being sent');
    return $this->view('emails.admin-warning')
        ->to('[email protected]', 'Admin Test')
        ->subject('Subject here');
}

if I put something like this in a mailable, I can catch it in the AppServiceProvider boot method using this code

Queue::failing(function (JobFailed $event) {
    if ($event->exception->getMessage() == 'This email is not being sent') {
        // write to log
        \Log::error('This email is not being sentaaa');
        $event->job->release(10);
    }

this catches it fine, writes to the log fine. Rerunning the job though doesn't work as I expected, depending on the horizon config.

'supervisor-1' => [ 
        'connection' => 'redis',
        'queue' => ['default'],
        'balance' => 'auto',
        'minProcesses' => 1,
        'maxProcesses' => 6,
        'tries' => 1,
        'timeout' => 7200,
],

if tries is set to 1 like above, the retry will fail without trying again and with an error that it has taken the max number of tries.

'supervisor-1' => [ 
        'connection' => 'redis',
        'queue' => ['default'],
        'balance' => 'auto',
        'minProcesses' => 1,
        'maxProcesses' => 6,
        'tries' => 2,
        'timeout' => 7200,
],

If tries is 2, then it tries a second time on it's own before even hitting the Queue::failing code and when it does get to that, the same thing as above happens, it fails without trying again.

I just want it to rerun the job one more time, the same way it does in horizon interface when you rerun it from there.

0

There are 0 answers