Basic Laravel job throws: "Serialization of 'Closure' is not allowed" on failure - php

I have created a very basic queue job:
<?php
namespace App\Jobs;
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 FailingJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 1;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct()
{
// nothing
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
// nothing
}
/**
* Called when the job fails
*
* #param Exception $exception
*/
public function failed(Exception $exception) {
// nothing
}
}
and I dispatch it like so: FailingJob::dispatch();. This works fine.
Now I am purposefully adding "bugged" code in order for the job to fail, but instead of gracefully making the job fail,
I get the following exception:
Serialization of 'Closure' is not allowed.
I'm not sure where this is coming from, because this job is basically empty. I would like to use the failed() function in order to handle failures, but I can't even do that because this exception gets thrown when the job fails.
For reference, this is the code I use to make the job fail:
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
xxxxxx
// ^ This will make the job fail
}

Related

Handle Method not being called in Laravel Redis Queue

When adding an item to the queue, for some reason the handle method is not being called.
The Log entry in __construct is appearing but when attempting to log in handle(), nothing appears.
The method i'm using to dispatch is ProcessImport::dispatch($path, $task->task_id);
My queue service is configured to use Redis, and redis is storing all the data accordingly.
I am using Laravel 8. What could be wrong?
<?php
namespace App\Jobs;
use App\Models\Tasks;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Http\Controllers\Products\Products;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Queue;
use Illuminate\Queue\Events\JobProcessing;
use Illuminate\Queue\Events\JobProcessed;
use Throwable;
class ProcessImport implements ShouldQueue, ShouldBeUnique
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $file_path;
protected $response;
protected $task;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($path, $task_id)
{
Log::info("Importing products (construct)");
$this->task = Tasks::where('task_id', $task_id)->first();
$this->file_path = $path;
Log::info('Importing ' . $path);
}
private function getFilePath() {
return $this->file_path;
}
/**
* Handle a job failure.
*
* #param \Throwable $exception
* #return void
*/
public function failed(Throwable $exception)
{
$this->task->failed($exception->getMessage());
}
/**
* Get the cache driver for the unique job lock.
*
* #return \Illuminate\Contracts\Cache\Repository
*/
public function uniqueVia()
{
return Cache::driver('redis');
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
Log::info("Importing products (handle)");
$this->task->start();
$products = new Products();
$products->importProductsFromCSV($this->getFilePath());
$this->task->success();
Log::info("End of importing products..");
}
}
You've just pushed the jobs onto the queue but haven't started a worker to process them. You can run the worker with:
php artisan queue:work

Laravel "^6.18.35" “Target [Illuminate\Contracts\Bus\Dispatcher] is not instantiable.”

Im trying to test a job in laravel but with no success, when the job is called from a method inside a controller i get the following error:
“Target [Illuminate\Contracts\Bus\Dispatcher] is not instantiable.”
I already tried AltThree Bus command as an alternative.
Controller method where thw job is called
public function onOpen(ConnectionInterface $conn) {
// Store the new connection to send messages to later
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
Updates::dispatch();
}
Job Class
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class Updates implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
echo "this is a update";
}
}

How can i pass a closure function to a laravel queue dispatch method

I want to pass a closure function to job dispatch method of Laravel queue. But i am getting "Serialization of 'Closure' is not allowed" exception. Can anyone please tell me how i can be able to pass closure function to the dispatch method?
Here are the controller codes:
public function syncProductByQueue($id){
$syncCallback=function() use($id){
$this->syncProduct($id);
};
ProcessSyncImport::dispatch($syncCallback);
}
And here is the job class:
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class ProcessSyncImport implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* #return void
*/
private $syncCallBack;
public function __construct($syncCallBack)
{
$this->syncCallBack= $syncCallBack;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$syncCallBack();
}
}

Laravel scheduler job triggers failure event even though it doesn't fail

I am using the Laravel scheduler to run a job and if the job fails I want to write to the log and get sent an email. However as soon as I set it up even though the job was running fine I started getting emails and output in the log so for some reason Laravel is treating the job as if it's failed when it hasn't. Also if I look at the job in Telescope the status just stays on pending and never shows as complete or failed. I am using sync as my queue driver.
Here is my kernel.php file:
<?php
namespace App\Console;
use Log;
use App\Company;
use App\Jobs\ProcessPayments;
use App\Jobs\ProcessCompanyTiers;
use Illuminate\Console\Scheduling\Schedule;
use App\Jobs\ProcessPartialDiscountPayments;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
\App\Console\Commands\ProcessPartialDiscountPayments::class
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->job(new ProcessPartialDiscountPayments)
->onSuccess(function () {
Log::info('ProcessPartialDiscountPayments scheduled task successfully ran');
})
->onFailure(function () {
Log::info('ProcessPartialDiscountPayments errored and did not complete');
})
->emailOutputOnFailure(config('app.webmaster_email'));
}
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
/**
* Get the timezone that should be used by default for scheduled events.
*
* #return \DateTimeZone|string|null
*/
protected function scheduleTimezone()
{
return 'Europe/London';
}
}
And here is the job file:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Jobs\ProcessCompanyPayment;
use App\{ Company, DiscountCode };
use Log;
use Carbon\Carbon;
class ProcessPartialDiscountPayments
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $code_datetime;
protected $datetime_to;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct()
{
Log::info('Running ProcessPartialDiscountPayments');
$datetime = Carbon::now();
$this->code_datetime = $datetime->format('Y-m-d H:i');
$this->datetime_to = $datetime->format('Y-m-d H:i:s.v');
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$discount_codes = DiscountCode::whereRaw("left(convert(varchar(20), ValidTo, 120), 16) = '".$this->code_datetime."'")->get();
Log::info('Found '.$discount_codes->count().' discount codes');
if(!empty($discount_codes)) {
foreach($discount_codes as $discount_code) {
if($discount_code->companies->count() > 0) {
foreach($discount_code->companies as $company) {
$active_code = $company->discount_code($company->balance_at($this->datetime_to), $this->code_datetime);
if($active_code && $active_code->Id == $discount_code->Id) {
Log::info('Processing #'.$company->Id.': '.$company->Name);
ProcessCompanyPayment::dispatch($company, $this->datetime_to);
}
}
}
}
}
}
}
Here is the log entries that get generated when it runs:
[2019-12-19 12:32:03] local.INFO: Scheduler running
[2019-12-19 12:32:03] local.INFO: Running ProcessPartialDiscountPayments
[2019-12-19 12:32:03] local.INFO: Found 0 discount codes
[2019-12-19 12:32:03] local.INFO: ProcessPartialDiscountPayments errored and did not complete
Currently $discount_codes is always empty so the expected output should be that the handle function just writes to the log saying it hasn't found any and then the job completes.

The failed() method is not being called when an Job fails in Laravel 5.4

Currently im creating a job to be queued but for some reason the failed() method is not being triggered when the code executed in the handle() method of the job throws an exception. Is this some kind of bug in Laravel or am I doing something wrong? the Queue::failing() method in my AppServiceProvider IS being called
<?php
namespace App\Jobs;
use App\Models\Email;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class MyCommand implements ShouldQueue
{
use InteractsWithQueue, Queueable, SerializesModels;
protected $lead;
/**
* Create a new job instance.
*/
public function __construct($lead)
{
$this->lead = $lead;
}
/**
* Execute the job.
*/
public function handle()
{
throw new \Exception("error!");
}
/**
* The job failed to process.
*
* #param \Exception $exception
*/
public function failed(\Exception $exception)
{
\Log::critical('wooot');
}
}
In the above job. The failed() method is never being called. We use supervisor to keep the queue running
Thank
It looks like the failed() method was being called but because of the $lead property not being public. I got an exception when I wanted to retrieve the contents of the property.

Categories