TGA
TGA

Reputation: 93

Notification not Queuable on Laravel 5.4 (SlackMessage)

I started to use notification system on Slack provided by Laravel 5.4 and it is awesome (src: https://laravel.com/docs/5.4/notifications)!

However I have a problem to notify with a queue it triggers an Exception: Serialization of 'Closure' is not allowed in /var/www/project_test/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:125

Can you help me please, what is my mistake ?

Information :

Here my code in app/Notifications/Slack.php :

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\SlackMessage;

class Slack extends Notification implements ShouldQueue
{
    use Queueable;

    private $channel;
    private $username;
    private $icon;
    private $message;
    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct(String $channel = '', String $username = '', String $icon = '', String $message = '')
    {
        $this->channel = $channel;
        $this->username = $username;
        $this->icon = $icon;
        $this->message = $message;
    }
    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['slack'];
    }
    /**
    * Get the Slack representation of the notification.
    *
    * @param  mixed  $notifiable
    * @return SlackMessage
    */
    public function toSlack($notifiable)
    {
        return (new SlackMessage)
                ->from($this->username, $this->icon)
                ->to($this->channel)
                ->content($this->message);
    }
    /**
    * Get the array representation of the notification.
    *
    * @param  mixed  $notifiable
    * @return array
    */
    public function toArray($notifiable)
    {
        return [
            'channel' => $this->channel,
            'username' => $this->username,
            'icon' => $this->icon,
            'message' => $this->message,
        ];
    }
}

Here my code in app/Providers/AppServiceProvider.php which use slack notifications:

namespace App\Providers;
use Queue;
use Carbon\Carbon;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Log;
use Illuminate\Queue\Events\JobFailed;
use Illuminate\Notifications\Notifiable;
use App\Notifications\Slack;

class AppServiceProvider extends ServiceProvider
{
    use Notifiable;
    /**
     * Route notifications for the Slack channel.
     *
     * @return string
     */
    public function routeNotificationForSlack()
    {
        return 'http://hook.slack.com/XXXXXx/my_slack_endpoint';
    }
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        // When a queue job fail
        Queue::failing(function (JobFailed $event) {
            // Notify team of failing job
            $when = Carbon::now()->addSeconds(10);
            $this->notify((new Slack('slack_channel', 'slack_username', 'slack_icon', 'Job Failed !'))->delay($when));
        });
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Full error dump :

local.ERROR: Exception: Serialization of 'Closure' is not allowed in /var/www/project_test/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:125
Stack trace:
#0 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Queue/Queue.php(125): serialize(Object(Illuminate\Notifications\SendQueuedNotifications))
#1 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Queue/Queue.php(106): Illuminate\Queue\Queue->createObjectPayload(Object(Illuminate\Notifications\SendQueuedNotifications))
#2 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Queue/Queue.php(86): Illuminate\Queue\Queue->createPayloadArray(Object(Illuminate\Notifications\SendQueuedNotifications), '', NULL)
#3 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Queue/DatabaseQueue.php(108): Illuminate\Queue\Queue->createPayload(Object(Illuminate\Notifications\SendQueuedNotifications), '')
#4 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(181): Illuminate\Queue\DatabaseQueue->later(Object(Carbon\Carbon), Object(Illuminate\Notifications\SendQueuedNotifications))
#5 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(159): Illuminate\Bus\Dispatcher->pushCommandToQueue(Object(Illuminate\Queue\DatabaseQueue), Object(Illuminate\Notifications\SendQueuedNotifications))
#6 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(73): Illuminate\Bus\Dispatcher->dispatchToQueue(Object(Illuminate\Notifications\SendQueuedNotifications))
#7 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(160): Illuminate\Bus\Dispatcher->dispatch(Object(Illuminate\Notifications\SendQueuedNotifications))
#8 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(61): Illuminate\Notifications\NotificationSender->queueNotification(Array, Object(App\Notifications\Slack))
#9 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Notifications/ChannelManager.php(36): Illuminate\Notifications\NotificationSender->send(Array, Object(App\Notifications\Slack))
#10 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Notifications/RoutesNotifications.php(18): Illuminate\Notifications\ChannelManager->send(Object(App\Providers\AppServiceProvider), Object(App\Notifications\Slack))
#11 /var/www/project_test/app/Providers/AppServiceProvider.php(57): App\Providers\AppServiceProvider->notify(Object(App\Notifications\Slack))
#12 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(334): App\Providers\AppServiceProvider->App\Providers\{closure}(Object(Illuminate\Queue\Events\JobFailed))
#13 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(199): Illuminate\Events\Dispatcher->Illuminate\Events\{closure}('Illuminate\\Queu...', Array)
#14 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(172): Illuminate\Events\Dispatcher->dispatch('Illuminate\\Queu...', Array, false)
#15 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Queue/FailingJob.php(36): Illuminate\Events\Dispatcher->fire(Object(Illuminate\Queue\Events\JobFailed))
#16 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(392): Illuminate\Queue\FailingJob::handle('database', Object(Illuminate\Queue\Jobs\DatabaseJob), Object(Swift_TransportException))
#17 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(378): Illuminate\Queue\Worker->failJob('database', Object(Illuminate\Queue\Jobs\DatabaseJob), Object(Swift_TransportException))
#18 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(321): Illuminate\Queue\Worker->markJobAsFailedIfWillExceedMaxAttempts('database', Object(Illuminate\Queue\Jobs\DatabaseJob), 3, Object(Swift_TransportException))
#19 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(295): Illuminate\Queue\Worker->handleJobException('database', Object(Illuminate\Queue\Jobs\DatabaseJob), Object(Illuminate\Queue\WorkerOptions), Object(Swift_TransportException))
#20 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(258): Illuminate\Queue\Worker->process('database', Object(Illuminate\Queue\Jobs\DatabaseJob), Object(Illuminate\Queue\WorkerOptions))
#21 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(110): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\DatabaseJob), 'database', Object(Illuminate\Queue\WorkerOptions))
#22 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(100): Illuminate\Queue\Worker->daemon('database', 'default,q-mail', Object(Illuminate\Queue\WorkerOptions))
#23 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(83): Illuminate\Queue\Console\WorkCommand->runWorker('database', 'default,q-mail')
#24 [internal function]: Illuminate\Queue\Console\WorkCommand->fire()
#25 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(29): call_user_func_array(Array, Array)
#26 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(87): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#27 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(31): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#28 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Container/Container.php(524): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#29 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Console/Command.php(182): Illuminate\Container\Container->call(Array)
#30 /var/www/project_test/vendor/symfony/console/Command/Command.php(265): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#31 /var/www/project_test/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))
#32 /var/www/project_test/vendor/symfony/console/Application.php(826): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#33 /var/www/project_test/vendor/symfony/console/Application.php(189): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#34 /var/www/project_test/vendor/symfony/console/Application.php(120): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#35 /var/www/project_test/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(123): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#36 /var/www/project_test/artisan(35): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#37 {main}  

Thank by advance for your responses,

Rergards

Upvotes: 1

Views: 1175

Answers (2)

Luca C.
Luca C.

Reputation: 12594

Make sure you have implemented ShouldQueue and use Queueable trait:

class MyNotification extends Notification implements ShouldQueue{
    use Queueable;

    // ...
}

Upvotes: 0

Sergey Neskhodovskiy
Sergey Neskhodovskiy

Reputation: 382

Loooks like themsaid answered your issue request on laravel bug tracker. To save others a click, I'll quote that reply here if you don't mind:

Don't use the Illuminate\Notifications\Notifiable, it's meant to be used with Eloquent models, now the Queue driver will try to serliaize your service provider thinking it's the notifiable, this is something you don't want.

Instead you can create a MySlack class or something that uses Notifiable and you send the notification from the service provider like:

Notification::Send(new MySlack(), new MyNotification());

Upvotes: 1

Related Questions