Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unserialize issue when Mailable is queued #22727

Closed
designvoid opened this issue Jan 10, 2018 · 8 comments
Closed

Unserialize issue when Mailable is queued #22727

designvoid opened this issue Jan 10, 2018 · 8 comments

Comments

@designvoid
Copy link

designvoid commented Jan 10, 2018

  • Laravel Version: 5.5.25
  • PHP Version: 7.1.13
  • Database Driver & Version: MySQL v5.7.2

Description:

I have 3 separate servers (for reference):

  1. Application server with the application, Horizon and supervisord monitoring Horizon
  2. Redis server
  3. MySQL server

I have created a mailable:

class CourseVisible extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;

    /**
     * The course instance.
     *
     * @var Course
     */
    public $course;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct(Course $course)
    {
        $course->load(['award:id,name']);
        $this->course = $course;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->markdown('emails.course.visible');
    }
}

Which is fired thusly:

    $course->visible = ($course->visible == true ? false : true);
    $course->save();
    Mail::to($course->notifiableUsers())->send(new CourseVisible($course));

When the queue is processed I am seeing the following errors in Horizon:

Undefined property: Illuminate\Contracts\Database\ModelIdentifier::$visible

Which is referring to this in the markdown view:

@if($course->visible == 1)

# The {{ $course->award->name }} {{ $course->title }} ({{ $course->year }}) course has been published to the website.

@else

# The {{ $course->award->name }} {{ $course->title }} ({{ $course->year }}) course has been unpublished from the website.

@endif

If I remove the ShouldQueue/Queueable portions and fire the email without queuing it works perfectly but as soon as I push it to the queue it fails.

I should also mention that I have another job that is fired by a model saving event that is queued and also passes a model instance in to a constructor and this works perfectly when queued and subsequently run.

Stack Trace

ErrorException: Undefined property: Illuminate\Contracts\Database\ModelIdentifier::$visible in /var/www/html/someurl.co.uk/prospectus/storage/framework/views/8b4dc10ef84d66c2b8ec041a4686f4e0c0892a82.php:3
	Stack trace:
	#0 /var/www/html/someurl.co.uk/prospectus/storage/framework/views/8b4dc10ef84d66c2b8ec041a4686f4e0c0892a82.php(3): Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(8, 'Undefined prope...', '/var/www/html/d...', 3, Array)
	#1 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/View/Engines/PhpEngine.php(43): include('/var/www/html/d...')
	#2 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/View/Engines/CompilerEngine.php(59): Illuminate\View\Engines\PhpEngine->evaluatePath('/var/www/html/d...', Array)
	#3 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/View/View.php(137): Illuminate\View\Engines\CompilerEngine->get('/var/www/html/d...', Array)
	#4 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/View/View.php(120): Illuminate\View\View->getContents()
	#5 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/View/View.php(85): Illuminate\View\View->renderContents()
	#6 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Mail/Markdown.php(61): Illuminate\View\View->render()
	#7 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Mail/Mailable.php(217): Illuminate\Mail\Markdown->render('emails.course.v...', Array)
	#8 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Mail/Mailable.php(189): Illuminate\Mail\Mailable->buildMarkdownView()
	#9 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Mail/Mailable.php(119): Illuminate\Mail\Mailable->buildView()
	#10 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Mail/SendQueuedMailable.php(52): Illuminate\Mail\Mailable->send(Object(Illuminate\Mail\Mailer))
	#11 [internal function]: Illuminate\Mail\SendQueuedMailable->handle(Object(Illuminate\Mail\Mailer))
	#12 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(29): call_user_func_array(Array, Array)
	#13 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(87): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
	#14 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(31): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
	#15 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/Container.php(549): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
	#16 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(94): Illuminate\Container\Container->call(Array)
	#17 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(114): Illuminate\Bus\Dispatcher->Illuminate\Bus\{closure}(Object(Illuminate\Mail\SendQueuedMailable))
	#18 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(102): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Mail\SendQueuedMailable))
	#19 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(98): Illuminate\Pipeline\Pipeline->then(Object(Closure))
	#20 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(49): Illuminate\Bus\Dispatcher->dispatchNow(Object(Illuminate\Mail\SendQueuedMailable), false)
	#21 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(76): Illuminate\Queue\CallQueuedHandler->call(Object(Illuminate\Queue\Jobs\RedisJob), Array)
	#22 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(320): Illuminate\Queue\Jobs\Job->fire()
	#23 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(270): Illuminate\Queue\Worker->process('redis', Object(Illuminate\Queue\Jobs\RedisJob), Object(Illuminate\Queue\WorkerOptions))
	#24 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(114): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\RedisJob), 'redis', Object(Illuminate\Queue\WorkerOptions))
	#25 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(101): Illuminate\Queue\Worker->daemon('redis', 'default', Object(Illuminate\Queue\WorkerOptions))
	#26 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(85): Illuminate\Queue\Console\WorkCommand->runWorker('redis', 'default')
	#27 [internal function]: Illuminate\Queue\Console\WorkCommand->handle()
	#28 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(29): call_user_func_array(Array, Array)
	#29 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(87): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
	#30 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(31): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
	#31 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/Container.php(549): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
	#32 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Illuminate\Container\Container->call(Array)
	#33 /var/www/html/someurl.co.uk/prospectus/vendor/symfony/console/Command/Command.php(252): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
	#34 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Console/Command.php(167): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
	#35 /var/www/html/someurl.co.uk/prospectus/vendor/symfony/console/Application.php(936): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
	#36 /var/www/html/someurl.co.uk/prospectus/vendor/symfony/console/Application.php(240): Symfony\Component\Console\Application->doRunCommand(Object(Laravel\Horizon\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
	#37 /var/www/html/someurl.co.uk/prospectus/vendor/symfony/console/Application.php(148): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
	#38 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Console/Application.php(88): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
	#39 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(121): Illuminate\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
	#40 /var/www/html/someurl.co.uk/prospectus/artisan(35): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
	#41 {main}
	Next ErrorException: Undefined property: Illuminate\Contracts\Database\ModelIdentifier::$visible (View: /var/www/html/someurl.co.uk/prospectus/resources/views/emails/course/visible.blade.php) in /var/www/html/someurl.co.uk/prospectus/storage/framework/views/8b4dc10ef84d66c2b8ec041a4686f4e0c0892a82.php:3
	Stack trace:
	#0 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/View/Engines/PhpEngine.php(45): Illuminate\View\Engines\CompilerEngine->handleViewException(Object(ErrorException), 0)
	#1 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/View/Engines/CompilerEngine.php(59): Illuminate\View\Engines\PhpEngine->evaluatePath('/var/www/html/d...', Array)
	#2 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/View/View.php(137): Illuminate\View\Engines\CompilerEngine->get('/var/www/html/d...', Array)
	#3 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/View/View.php(120): Illuminate\View\View->getContents()
	#4 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/View/View.php(85): Illuminate\View\View->renderContents()
	#5 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Mail/Markdown.php(61): Illuminate\View\View->render()
	#6 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Mail/Mailable.php(217): Illuminate\Mail\Markdown->render('emails.course.v...', Array)
	#7 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Mail/Mailable.php(189): Illuminate\Mail\Mailable->buildMarkdownView()
	#8 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Mail/Mailable.php(119): Illuminate\Mail\Mailable->buildView()
	#9 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Mail/SendQueuedMailable.php(52): Illuminate\Mail\Mailable->send(Object(Illuminate\Mail\Mailer))
	#10 [internal function]: Illuminate\Mail\SendQueuedMailable->handle(Object(Illuminate\Mail\Mailer))
	#11 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(29): call_user_func_array(Array, Array)
	#12 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(87): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
	#13 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(31): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
	#14 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/Container.php(549): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
	#15 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(94): Illuminate\Container\Container->call(Array)
	#16 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(114): Illuminate\Bus\Dispatcher->Illuminate\Bus\{closure}(Object(Illuminate\Mail\SendQueuedMailable))
	#17 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(102): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Mail\SendQueuedMailable))
	#18 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(98): Illuminate\Pipeline\Pipeline->then(Object(Closure))
	#19 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(49): Illuminate\Bus\Dispatcher->dispatchNow(Object(Illuminate\Mail\SendQueuedMailable), false)
	#20 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(76): Illuminate\Queue\CallQueuedHandler->call(Object(Illuminate\Queue\Jobs\RedisJob), Array)
	#21 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(320): Illuminate\Queue\Jobs\Job->fire()
	#22 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(270): Illuminate\Queue\Worker->process('redis', Object(Illuminate\Queue\Jobs\RedisJob), Object(Illuminate\Queue\WorkerOptions))
	#23 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(114): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\RedisJob), 'redis', Object(Illuminate\Queue\WorkerOptions))
	#24 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(101): Illuminate\Queue\Worker->daemon('redis', 'default', Object(Illuminate\Queue\WorkerOptions))
	#25 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(85): Illuminate\Queue\Console\WorkCommand->runWorker('redis', 'default')
	#26 [internal function]: Illuminate\Queue\Console\WorkCommand->handle()
	#27 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(29): call_user_func_array(Array, Array)
	#28 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(87): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
	#29 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(31): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
	#30 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Container/Container.php(549): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
	#31 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Illuminate\Container\Container->call(Array)
	#32 /var/www/html/someurl.co.uk/prospectus/vendor/symfony/console/Command/Command.php(252): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
	#33 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Console/Command.php(167): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
	#34 /var/www/html/someurl.co.uk/prospectus/vendor/symfony/console/Application.php(936): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
	#35 /var/www/html/someurl.co.uk/prospectus/vendor/symfony/console/Application.php(240): Symfony\Component\Console\Application->doRunCommand(Object(Laravel\Horizon\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
	#36 /var/www/html/someurl.co.uk/prospectus/vendor/symfony/console/Application.php(148): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
	#37 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Console/Application.php(88): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
	#38 /var/www/html/someurl.co.uk/prospectus/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(121): Illuminate\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
	#39 /var/www/html/someurl.co.uk/prospectus/artisan(35): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
	#40 {main}
@sisve
Copy link
Contributor

sisve commented Jan 10, 2018

It sounds like the process running the queue does not have the $visible property. This happens if you havn't deployed to the queue server, or forgot to restart the worker after deploying.

@designvoid
Copy link
Author

Hi @sisve how do you mean "deployed to the queue server" and I have run horizon:terminate and horizon:purge after deploying the application on the application server

@sisve
Copy link
Contributor

sisve commented Jan 10, 2018

Ah, now I see that it's looking for ModelIdentifier::$visible. That is weird. It would happen if the queue-worker isn't using the SerializesModels trait which transforms models to identifiers and back again. Once again, this would happen if you're not executing identical code everywhere.

Can you update your issue with a complete stack trace?

@designvoid
Copy link
Author

designvoid commented Jan 10, 2018

done @sisve
With regards to identical code - the only difference between local Homestead and production is the .env file and the entire codebase for the app is just in one place, there's nothing additional on the queue/redis server

@themsaid
Copy link
Member

I can't replicate this, models are serialized and unserialized back properly when the mailable is queued, I think you'll need to investigate this more since you're the only one who can replicate.

@rusinov-artem
Copy link

Hi! I faced the same problem and invistigate it

it appears when i was tring to serialize($mailable), to save it into my log and after then
do
Mail::send($mailable);

The problem is in call serialize($mailable); coz it invoke SerializesModels::__sleep() wich
make all models in $mailable transform into
Illuminate\Contracts\Database\ModelIdentifier:
and after it I can no more call $mailable->model->property

in my case workaround is to call serialize(clone $mailable)

@themsaid
Copy link
Member

Thanks @rusinov-artem for the feedback, what you said makes sense, if the instance is serialized already it'll cause the problem mentioned in this issue.

@rusinov-artem
Copy link

@themsaid
As for me its strange that serialaize($mailable) actualy change my $mailable object instead of just return to me a string represintation of $mailable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants