Ошибки уведомления очереди Laravel: сериализация «Закрытия» не разрешена

Я создал почтовое уведомление, которое успешно работает, но при попытке поставить его в очередь я получаю следующую ошибку:

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

Ниже приведен мой код, который, как мне кажется, вызывает ошибку:

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]);
}

Я не совсем уверен, откуда берется «Закрытие», которое он пытается сериализовать. Я попытался добавить ->render() в конец View::make, но это, похоже, не имело значения. Я полагаю, что это может иметь какое-то отношение к функции view MailMessage, но я не совсем уверен.

Еще раз, это уведомление отлично работает, когда оно не поставлено в очередь.

Любая помощь будет оценена по достоинству.


person Brian Glaz    schedule 26.04.2017    source источник
comment
Если вы действительно думаете, что это именно в этих строках, определите, какая именно строка, отследив строку, выдающую ошибку, или используя пошаговую отладку, или операторы выхода после каждой, чтобы определить, какая именно строка выдает ошибку. Тогда вы можете сосредоточиться на проблеме.   -  person Paul Jerome Bordallo    schedule 26.04.2017
comment
@PaulJeromeBordallo Я знаю, какая строка вызывает ошибку. Трассировка стека бесполезна, так как все указывает на основной код laravel. Я знаю, что это за ошибка, я просто не знаю, как ее исправить.   -  person Brian Glaz    schedule 26.04.2017


Ответы (1)


Даже если вопрос довольно старый, я публикую его для дальнейшего использования.

Проблема возникает, когда очередь пытается сериализовать экземпляр уведомления. Это делается путем сериализации каждого свойства объекта уведомления. У меня была такая же проблема, потому что я делал что-то вроде

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

в моем классе уведомлений. Как только уведомление помещено в SendQueuedNotification, оно будет сериализовано обработчиком Queue. Во время этого процесса каждое свойство SendQueuedNotification будет сериализовано, включая наш собственный экземпляр уведомления и его свойства. Все потерпит неудачу, когда сериализатор попытается сериализовать экземпляр $exception; по какой-то причине класс исключения не сериализуем, потому что он, вероятно, содержит замыкание в своих свойствах. Итак, что сработало для меня, так это изменить конструктор следующим образом

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

Теперь все свойства уведомлений полностью сериализуемы, и все работает как положено.

Другим решением является использование __wakeup() и __sleep() для настройки сериализации и десериализации вашего экземпляра уведомления.

Надеюсь, это поможет понять вашу проблему.

person Desh901    schedule 25.07.2017