2

I've created a mail notification that works successfully, but when trying to queue it, I get the following error:

Uncaught Exception: Serialization of 'Closure' is not allowed in /vendor/laravel/framework/src/Illuminate/Queue/Queue.php:125

Below is my code that I believe is causing the error:

public function toMail($notifiable)
{
    $view_file = 'emails.verifyEmail';
    $view = View::make($view_file, ['invitationToken' => $this->invitationToken, 'team_name' => $this->team->name, 'team_domain' => $this->team->domain ]);

    $view = new HtmlString(with(new CssToInlineStyles)->convert($view));

    return (new MailMessage)
        ->subject('Email Verification')
        ->view('emails.htmlBlank', ['bodyContent' => $view]);
}

I am not exactly sure where the 'Closure' it's trying to serialize is coming from. I tried tacking on ->render() to the end of View::make but that did not seem to make a difference. I believe it may have something to do with the view function of the MailMessage but I'm not really sure.

Once again, this notification works perfectly when it is not being Queued.

Any help would be appreciated.

Brian Glaz
  • 15,468
  • 4
  • 37
  • 55
  • If you really think it's in those lines, identify which line exactly by tracing from the line giving the error, or using step debugging, or "exit" statements after each to determine which line exactly is throwing the error. Then you can home in on the problem. – Paul Jerome Bordallo Apr 26 '17 at 20:23
  • @PaulJeromeBordallo I know which line is causing the error. The stack trace is not helpful as all of it points to core laravel code. I know what the error is, I just don't know how to fix it. – Brian Glaz Apr 26 '17 at 20:41

1 Answers1

3

Even if the question is pretty old, i'm posting this for future reference.

The problem occurs when the Queue tries to serialize the notification instance. This is done by serializing every property of the notification object. I had the same problem because i was doing something like

public function __construct(\Exception $ex){
   $this->exception = $exception;
}

in my notification class. Once the notification is wrapped in SendQueuedNotification it will be serialized by the Queue handler. During this process every property of SendQueuedNotification will be serialized, including our custom notification instance and its properties. Everything will fail when the serializer will try to serialize $exception instance; for some reason the exception class is unserializable because it probably contains a closure within its properties. So what worked for me was changing the constructor as follows

public function __construct(\Exception $ex)
{
    $this->exceptionClass = get_class($ex);
    $this->exceptionMessage = $ex->getMessage();
    $this->exceptionLine = $ex->getFile() . '@' . $ex->getLine();
    $this->exceptionCode = $ex->getCode();
}

Now all of the notification properties are fully serializable and everything works as expected.

Another solution is to use __wakeup() and __sleep() methods to customize the serialization and deserialization of your notification instance.

Hope it helps to understand your issue.

Desh901
  • 2,633
  • 17
  • 24