Serialization of 'Closure' is not allowed in Laravel 5.3 Email Queue
Asked Answered
E

5

19

I am willing to send email to list of email address using queue. Without using queue my code is working fine but with queue it's showing following error:

Exception in Queue.php line 86: Serialization of 'Closure' is not allowed

    in /home/hizbul/Development/Projects/Laravel/fastskool/vendor/laravel/framework/src/Illuminate/Queue/Queue.php line 86
    at serialize(object(SendMessageToStudent)) in Queue.php line 86
    at Queue->createPayload(object(SendMessageToStudent), '') in DatabaseQueue.php line 81
    at DatabaseQueue->push(object(SendMessageToStudent)) in Dispatcher.php line 184
    at Dispatcher->pushCommandToQueue(object(DatabaseQueue), object(SendMessageToStudent)) in Dispatcher.php line 159
    at Dispatcher->dispatchToQueue(object(SendMessageToStudent)) in Dispatcher.php line 73
    at Dispatcher->dispatch(object(SendMessageToStudent)) in DispatchesJobs.php line 17
    at Controller->dispatch(object(SendMessageToStudent)) in MessageController.php line 49
    at MessageController->store(object(Request))
    at call_user_func_array(array(object(MessageController), 'store'), array(object(Request))) in Controller.php line 55
    at Controller->callAction('store', array(object(Request))) in ControllerDispatcher.php line 44
    at ControllerDispatcher->dispatch(object(Route), object(MessageController), 'store') in Route.php line 189
    at Route->runController() in Route.php line 144
    at Route->run(object(Request)) in Router.php line 653
    at Router->Illuminate\Routing\{closure}(object(Request)) in Pipeline.php line 53
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in StaffAndAdmin.php line 40
    at StaffAndAdmin->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in ModuleManager.php line 29
    at ModuleManager->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in SwitchDatabaseConnection.php line 36
    at SwitchDatabaseConnection->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in SubstituteBindings.php line 41
    at SubstituteBindings->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in VerifyCsrfToken.php line 65
    at VerifyCsrfToken->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in ShareErrorsFromSession.php line 49
    at ShareErrorsFromSession->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in StartSession.php line 64
    at StartSession->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in AddQueuedCookiesToResponse.php line 37
    at AddQueuedCookiesToResponse->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in EncryptCookies.php line 59
    at EncryptCookies->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in Pipeline.php line 104
    at Pipeline->then(object(Closure)) in Router.php line 655
    at Router->runRouteWithinStack(object(Route), object(Request)) in Router.php line 629
    at Router->dispatchToRoute(object(Request)) in Router.php line 607
    at Router->dispatch(object(Request)) in Kernel.php line 268
    at Kernel->Illuminate\Foundation\Http\{closure}(object(Request)) in Pipeline.php line 53
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in Debugbar.php line 51
    at Debugbar->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in CheckForMaintenanceMode.php line 46
    at CheckForMaintenanceMode->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in Pipeline.php line 104
    at Pipeline->then(object(Closure)) in Kernel.php line 150
    at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 117
    at Kernel->handle(object(Request)) in index.php line 68

I am using database as queue driver.

Following is my Queue job handler code:

    class SendMessageToStudent implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SerializesModels;

    private $data;

    /**
     * Create a new job instance.
     *
     * @param Request $request
     */
    public function __construct(Request $request)
    {
        $this->data = $request;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $student = $this->data;
        $arrStudent = (new Message())->getEmailAddressList($student);
        Mail::to($arrStudent)->send(new MessageSent($student));
    }
}

and dispatcher code:

$this->dispatch(new SendMessageToStudent($request));

I am expecting a feasible solution.

Egad answered 16/9, 2017 at 7:43 Comment(0)
B
39

You cannot serialize request. Only eloquent model can be serialized and unserialzed. See here: https://laravel.com/docs/5.2/queues#writing-job-classes

You should use $request->all() instead of $request. Since Request is treated as closure.

Blida answered 16/9, 2017 at 9:27 Comment(1)
I was also doing same mistake.Somatist
G
7

Try removing this line from constructor:

$this->message = new Message();

and, in the handle directly initialise it.

$student = $this->data;
$arrStudent = (new Message())->getEmailAddressList($student);
Mail::to($arrStudent)->send(new MessageSent($student));
Gringo answered 16/9, 2017 at 7:50 Comment(1)
@Egad I faced a similar solution week back, it worked for me this way.Gringo
V
0

It happened to me in Laravel 5.6. I just added this:

use Illuminate\Support\Facades\Mail;

And everything worked well.

Vinyl answered 15/2, 2019 at 15:9 Comment(0)
O
0

You can implement Serializable interface in your request class. I made BaseRequest class for that and all requests inherit from it.

class BaseRequest extends FormRequest implements \Serializable
{

    /** @inheritDoc */
    public function serialize()
    {
        return json_encode($this->all());
    }

    /** @inheritDoc */
    public function unserialize($serialized)
    {
        $data = json_decode($serialized, true);
        $this->initialize($data);
    }

}
Oldster answered 5/5, 2021 at 9:53 Comment(0)
B
0

I solved a similar problem using Opi/SerializeClosure. It's straightforward to use and solves many problems with that.

https://github.com/opis/closure

You can install with:

composer require opis/closure

To use, just call SerializableClosure:

$next_method = SerializableClosure(function() use ($some_variable) {
                            my_function($some_variable);
                        });

When you need to call the serialized closure, call:

// Get Closure of method
$next_method = $next_method->getClosure();
// Call next method
$next_method();

I used this solution to create an async call using Jobs, like this:

// Call next method to continue the flow
ProcessCallNextMethod::dispatch(new SerializableClosure(function() use ($next_method) {
   $next_method();
}))->delay(now()->addSecond(30));
Breathing answered 20/4, 2024 at 22:14 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.