lumen-framework: Queueing mail throws an error

I’m trying to queue a mailable in Lumen 5.4, but run into a

FatalThrowableError in Mailable.php line 133:
Type error: Argument 1 passed to Illuminate\Mail\Mailable::queue() must be an instance of Illuminate\Contracts\Queue\Factory, null given, called in /home/vagrant/Code/.../vendor/illuminate/mail/Mailer.php on line 317

Using app('mailer')->to(env('MAIL_TO_ADDRESS'))->send(); works fine. I’ve checked that my mailable uses both Queueable and SerializesModels, extends Mailable and implements ShouldQueue. This might be related?

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 14
  • Comments: 19 (2 by maintainers)

Most upvoted comments

Working successfully by now. Thanks!

<?php

namespace App\Providers;

use Illuminate\Mail\Mailer;

class MailServiceProvider extends \Illuminate\Mail\MailServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function registerIlluminateMailer()
    {
        $this->app->singleton('mailer', function ($app) {
            $config = $app->make('config')->get('mail');

            // Once we have create the mailer instance, we will set a container instance
            // on the mailer. This allows us to resolve mailer classes via containers
            // for maximum testability on said classes instead of passing Closures.
            $mailer = new Mailer(
                $app['view'], $app['swift.mailer'], $app['events']
            );

            // The trick
            $mailer->setQueue($app['queue']);

            // Next we will set all of the global addresses on this mailer, which allows
            // for easy unification of all "from" addresses as well as easy debugging
            // of sent messages since they get be sent into a single email address.
            foreach (['from', 'reply_to', 'to'] as $type) {
                $this->setGlobalAddress($mailer, $config, $type);
            }

            return $mailer;
        });
        $this->app->configure('mail');
        // The job cannot be done without it
        $this->app->alias('mailer', \Illuminate\Contracts\Mail\Mailer::class);
    }
}

https://github.com/laravel/lumen-framework/issues/634

I have the same issue, any idea on a fix for this?

Further investigation:

$app->configure('queue');
$app->register(\Illuminate\Queue\QueueServiceProvider::class);

in bootstrap/app.php before registering the MailServiceProvider gives me this: PHP message: PHP Fatal error: Maximum function nesting level of '256' reached, aborting! in /src/api/vendor/illuminate/container/Container.php on line 647 Because in MailServiceProvider this is used:

if ($app->bound('queue')) {
    $mailer->setQueue($app['queue']);
}

which becomes an endless loop. If I DON’T register the QueueServiceProvider I get the same Type error: as @michaeldzjap.

EDIT: I fixed this in my own service provider, by explicitly setting $mailer->setQueue($app['queue']) without registering the QueueServiceProvider in bootstrap/app.php.

In my case for Lumen, It seems that it does not register the bindings for the queue service automatically - it’s lazily-loaded.

See registerQueueBindings() method.

That method is only called when you issue an $app->make('queue'); call. You can refer to the following lines in the repository:

https://github.com/laravel/lumen-framework/blob/5.5/src/Application.php#L893 https://github.com/laravel/lumen-framework/blob/5.5/src/Application.php#L219

What works for me is to make sure to call $app->make('queue'); before the queue service is first used.

// somewhere in my ServiceProvider class..

$this->app->make('queue');

$this->app->register(MailServiceProvider::class);

This issue is still not solved.Experiencing the same problem on lumen version 7 using beanstalkd queue. Error: Class ‘Illuminate\Mail\Mailable’ not found. Mail::send works fine.

All I had to do in Lumen was add $app->make('queue'); to my bootstrap/app.php file. I added it right after $app->withEloquent();. Anyone know if it’s okay there, or if it’s better to do it in a service provider as suggested above?

I experiences the same issue and I found at least a workaround - basically create your own MailDispatcher job that takes care of the asynchronous sending of mails:

http://stackoverflow.com/questions/42203416/bindingresolutionexception-when-sending-mails-in-lumen-jobs

$app->make(‘queue’); I registered this in AppServiceProvider It is working also for me in lumen 8+

In app.php file add $app->make(‘queue’); It worked for me.

I was lucky enough to meet this problem, too. I submitted a pull request, but it was rejected.

From lumen 5.2, support for illuminate/mail is not ideal.

@aldee07 So can you make bound method work for?

Do

$this->app->make('queue')

Then

$app->bound('queue')

Works?

It seems amazing.