Php 拉雷维尔:我如何使Redis排队作业失败?

Php 拉雷维尔:我如何使Redis排队作业失败?,php,laravel,Php,Laravel,在Laravel中,当运行Redis队列时,我无法获取作业类中调用的failed方法。我想确保我可以正确地记录它们,并将它们写入failed_jobs表 关于队列的Laravel文档 您可以直接在作业类上定义失败的方法,以便在发生故障时执行特定于作业的清理。这是向用户发送警报或恢复作业执行的任何操作的最佳位置导致作业失败的异常将传递给失败的方法: 我不确定Laravel认为什么是“导致工作失败的例外”。下面是一个非常简单的作业类。我的日志中显示的所有内容都是它不起作用和异常捕获 我使用以下命令启

在Laravel中,当运行Redis队列时,我无法获取作业类中调用的
failed
方法。我想确保我可以正确地记录它们,并将它们写入failed_jobs表

关于队列的Laravel文档

您可以直接在作业类上定义失败的方法,以便在发生故障时执行特定于作业的清理。这是向用户发送警报或恢复作业执行的任何操作的最佳位置导致作业失败的异常将传递给失败的方法

我不确定Laravel认为什么是“导致工作失败的例外”。下面是一个非常简单的作业类。我的日志中显示的所有内容都是
它不起作用
异常捕获

我使用以下命令启动此队列,特别是将
trys
设置为1,这样它就不会尝试重新运行作业

php artisan queue:work redis --queue=widgets --tries=1
如何调用失败的方法并使作业显示在failed_jobs表中

<?php
namespace App\Jobs;
use Exception;
use App\Processors\WidgetProcessor;

use Illuminate\Bus\Queueable;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class WidgetJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct($widget)
    {
        $this->widget = $widget;
    }

    public function handle(WidgetProcessor $processor)
    {
        Redis::throttle('WidgetJob')->allow(5)->every(60)->then(function () use ($processor) {
            try {
                $var = false;
                if($var == false) {
                    Log::notice('It did not work');
                    throw new Exception;
                } else {
                    Log::notice('It worked');
                }
            } catch(Exception $e) {
                Log::notice('Exception caught');
            }          
        }, function () {
            return $this->release(5);
        });
    }

    public function failed(Exception $exception)
    {
        Log::notice('failed was called');
    }
}

Laravel队列系统作为一个守护进程,负责拾取作业、运行作业并继续运行。如果你的工作“强\不”/“强”抛出异常,拉拉维尔会认为这是一项成功的工作。代码段中的问题是:

try {
  ... 
} catch(Exception $e) {
    Log::notice('Exception caught');
}
通过捕获异常,您不会让Laravel将此作业标记为失败

这里有两种选择:要么不使用
try…catch
,要么,如果您真的想使用它,按如下方式重新抛出异常:

try {
  ... 
} catch(Exception $e) {
    Log::notice('Exception caught');

    throw $e;
}

通过让异常冒泡,Laravel将使作业失败并调用
failed()
例程。

您正在捕获异常,这意味着
句柄
函数返回为
void
。毫无例外,作业已成功执行。让异常冒泡起来,这样Laravel会将其标记为失败。@MarcoAurélioDeleu不确定你的意思。我不能用“不抓不抓”的方法。当我试图删除throw语句时,我得到的是“它没有工作”。但是仍然没有调用fail方法。我发现,如果我抛出并捕获一个ReflectionException,那么会调用fail,但它会抱怨异常的类型。。。所以还没有完全达到目的。停止使用try-catch。如果捕获到异常,则不会触发fail,因为Laravel会认为作业已成功执行。如果您真的想使用Try-Catch,请在Catch块中重新显示异常。@MarcoAurélioDeleu对此表示感谢,让它正常工作。请发布一个答案,这样我就可以接受,你会得到一些分数:)