【发布时间】:2018-06-11 14:20:25
【问题描述】:
在 Laravel 中运行 Redis 队列时,我无法在 Job 类中调用 failed 方法。我想确保我可以正确记录它们并将它们写入 failed_jobs 表。
关于队列的 Laravel 文档states
您可以直接在您的作业类上定义一个失败的方法,允许您在发生故障时执行特定于作业的清理。这是向您的用户发送警报或恢复作业执行的任何操作的理想位置。 导致作业失败的异常将被传递给失败的方法:
我不能 100% 确定 Laravel 认为什么是“导致工作失败的异常”。下面是一个非常简单的工作类。我的日志中出现的只有It did not work 和exception caught。
我正在使用以下命令启动此队列,特别是将 tries 设置为 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');
}
}
【问题讨论】:
-
您正在捕获异常,这意味着
handle函数返回是void。无一例外,作业成功执行。让异常冒泡,以便 Laravel 将其标记为失败。 -
@MarcoAurélioDeleu 不确定您的意思。我不能使用没有捕获的尝试。当我尝试删除 throw 语句时,我只是得到“它不起作用”。但是仍然没有调用失败方法。我发现,如果我抛出并捕获一个 ReflectionException,那么 fail 确实会被调用,但它会抱怨 Exception 的类型......所以还没有。
-
停止使用 try catch。如果你捕获了异常,fail 将不会被触发,因为 Laravel 会认为作业已成功执行。如果你真的想使用 Try Catch,请在你的 catch 块中重新抛出异常。
-
@MarcoAurélioDeleu 谢谢你,让它工作。请发布一个答案,以便我接受它,你会得到一些积分:)