Reputation: 10096
In my multi-server application I use laravel's Queueing system in order to run background jobs. Sometimes in my logic I want to make my job to throw an exception so I can log it via a sentry using the laravel library that offers.
So in my job:
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use App\Model\Etable\User;
use App\Model\User;
class MyJob implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
/**
* @var int
*/
private $user_id;
/**
* @param int $user The user that has opted or deopted for newsletter consent
*/
public function __construct(int $id)
{
$this->user_id = $user_id;
}
public function handle(): void
{
/**
* @var User
*/
$user=User::useWritePdo()->find($this->user_id);
if(empty($user)){
throw new \Exception("No such a user with user id: {$this->user_id}");
}
// Rest of logic here
}
}
Once the exception is thrown, I will to be logged into sentry but also it will keep on respawning as laravel's logic for jobs is supposed to do so.
In my case I think it as waste of resources to keep an respawning the MyJob
in case that the user does not exist no value to keep on spawning because the logic itself cannot be performed in case that no user exists. On the other hand on any other error I want my job to keep on retrying till be able to sucessfully run again.
So how I can make my job not to respawn on specific errors? Even better would be as well if I can use the default logging method that laravel ofers in order to arbitary log an error into sentry as well via a sentry dedicated channel.
Upvotes: 0
Views: 1568
Reputation: 10096
The best and easier approach is once the code failt to check how many times has already be executed:
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use App\Model\Etable\User;
use App\Model\User;
class MyJob implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
/**
* @var int
*/
private $user_id;
/**
* @param int $user The user that has opted or deopted for newsletter consent
*/
public function __construct(int $id)
{
$this->user_id = $user_id;
}
public function handle(): void
{
/**
* @var User
*/
$user=User::useWritePdo()->find($this->user_id);
if(empty($user)){
if ($this->attempts() > 1) {
return;
}
throw new \Exception("No such a user with user id: {$this->user_id}");
}
// Rest of logic here
}
}
This is being achieved via the:
if ($this->attempts() > 1) {
return;
}
So you throw once the exception, the exception is being logged into the Sentry and then on the second time that will be executed it will just exit and never respawn.
Upvotes: 1
Reputation: 7236
Please note that failed jobs won't be re-run unless you explicitly run
php artisan queue:failed
You can throw an exception and handle it in boot method of AppServiceProvider, deleting the job to avoid its further re-tries. See documentation on how to do it.
Upvotes: 0