Reputation: 13892
I have a job that I've made to test how failures work:
<?php
namespace App\Jobs;
use App\ApiUser;
use App\Helpers\Helper;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class FakeJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
private $apiUser;
public function __construct(ApiUser $apiUser) {
$this->apiUser = $apiUser;
}
public function handle() {
throw new Exception('time is even');
}
public function failed(Exception $exception) {
// Send user notification of failure, etc...
$path = storage_path('logs/s3_logs/FakeJob_failed_' . Helper::generateRandomString(5) . '.txt');
file_put_contents($path, $exception->getMessage());
}
}
When I dispatch normally, it goes to the failed
function and writes to file exactly as expected.
However when I do it like FakeJob::dispatchNow($apiUser);
, it doesn't do that at all...
Is there a way to do dispatchNow
that runs on the same process as the request, but fails as if it were queued normally?
Because at the moment, it looks like my only way is to do something like:
$fakeJob = new FakeJob($apiUser);
try {
$fakeJob->handle();
} catch(Exception $e) {
$fakeJob->failed($e);
}
Which is... fine I guess, but not ideal.
Upvotes: 4
Views: 17815
Reputation: 45
A new dispatchSync()
method will be made available in Laravel 8.0 when it is released in the coming months.
It'll dispatch the job on the sync queue just like @Keshari's answer suggests.
Docs: https://laravel.com/docs/master/queues#synchronous-dispatching
Commit: https://github.com/laravel/framework/commit/0b3ed6859046258fba2e0ab3340bdab33e4c82bd
Upvotes: 4
Reputation: 1148
If I am not wrong dispatchNow() is used to run the job synchronously but unfortunately, it does not call the failed method.
If you want your failed method to be called on job failed then you can use the below code.
FakeJob::dispatch($apiUser)->onConnection('sync');
It will run the job synchronously and also execute the failed method.
Upvotes: 10
Reputation: 4012
Looking at the Laravel code base (and docs), the dispatchNow()
method executes the job synconously without interacting with any queues.
https://laravel.com/docs/5.8/queues#synchronous-dispatching
In essence it will simply call the handle()
method on your job and nothing more.
What you have done with your try/catch block may be the best solution for now but it could be worth raising this as a feature request with the Laravel team.
Upvotes: 4