Closed chuangbo closed 3 years ago
You need to share the full stack trace.
Please re-open with more information as noted by @themsaid
Thank you for the notes. The full stack trace is attached as below:
Exception {#7246
#message: "Serialization of 'Closure' is not allowed"
#code: 0
#file: "/app/vendor/laravel/framework/src/Illuminate/Queue/Queue.php"
#line: 157
trace: {
/app/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:157 { …}
/app/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:127 { …}
/app/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:104 { …}
/app/vendor/laravel/framework/src/Illuminate/Queue/SyncQueue.php:38 { …}
/app/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php:251 { …}
/app/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php:227 { …}
/app/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php:77 { …}
/app/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php:212 { …}
/app/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php:76 { …}
/app/vendor/laravel/framework/src/Illuminate/Notifications/ChannelManager.php:39 { …}
/app/vendor/laravel/framework/src/Illuminate/Notifications/RoutesNotifications.php:18 { …}
/app/vendor/psy/psysh/src/ExecutionLoopClosure.php:55 { …}
/app/vendor/psy/psysh/src/ExecutionLoopClosure.php:55 { …}
/app/vendor/psy/psysh/src/ExecutionClosure.php:96 { …}
/app/vendor/psy/psysh/src/Shell.php:370 { …}
/app/vendor/psy/psysh/src/Shell.php:341 { …}
/app/vendor/symfony/console/Application.php:166 { …}
/app/vendor/psy/psysh/src/Shell.php:316 { …}
/app/vendor/laravel/tinker/src/Console/TinkerCommand.php:81 { …}
/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:36 { …}
/app/vendor/laravel/framework/src/Illuminate/Container/Util.php:40 { …}
/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:93 { …}
/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:37 { …}
/app/vendor/laravel/framework/src/Illuminate/Container/Container.php:610 { …}
/app/vendor/laravel/framework/src/Illuminate/Console/Command.php:136 { …}
/app/vendor/symfony/console/Command/Command.php:255 { …}
/app/vendor/laravel/framework/src/Illuminate/Console/Command.php:121 { …}
/app/vendor/symfony/console/Application.php:971 { …}
/app/vendor/symfony/console/Application.php:290 { …}
/app/vendor/symfony/console/Application.php:166 { …}
/app/vendor/laravel/framework/src/Illuminate/Console/Application.php:93 { …}
/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:129 { …}
/app/artisan:37 {
› $input = new Symfony\Component\Console\Input\ArgvInput,
› new Symfony\Component\Console\Output\ConsoleOutput
› );
arguments: {
$input: Symfony\Component\Console\Input\ArgvInput {#25 …}
$output: Symfony\Component\Console\Output\ConsoleOutput {#23 …}
}
}
}
}
@taylorotwell @themsaid Is it possible that we re-open this?
I see you're using Tinker. Are you maybe using the wrong way to send these jobs?
@driesvints It wasn't from the dispatch
helper, it was $user->notify(new SomeMessage('test'))
from tinker. But I'll try to call it from a normal route instead.
Tried call $user->notify(new SomeMessage('test'))
from a http route seems throwing the same exception.
[2021-01-15 22:36:29] local.ERROR: Serialization of 'Closure' is not allowed {"userId":4,"exception":"[object] (Exception(code: 0): Serialization of 'Closure' is not allowed at /app/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:156)
[stacktrace]
#0 /app/vendor/laravel/framework/src/Illuminate/Queue/Queue.php(156): serialize(Object(Illuminate\\Notifications\\SendQueuedNotifications))
#1 /app/vendor/laravel/framework/src/Illuminate/Queue/Queue.php(126): Illuminate\\Queue\\Queue->createObjectPayload(Object(Illuminate\\Notifications\\SendQueuedNotifications), NULL)
#2 /app/vendor/laravel/framework/src/Illuminate/Queue/Queue.php(104): Illuminate\\Queue\\Queue->createPayloadArray(Object(Illuminate\\Notifications\\SendQueuedNotifications), NULL, '')
#3 /app/vendor/laravel/framework/src/Illuminate/Queue/SyncQueue.php(38): Illuminate\\Queue\\Queue->createPayload(Object(Illuminate\\Notifications\\SendQueuedNotifications), NULL, '')
#4 /app/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(251): Illuminate\\Queue\\SyncQueue->push(Object(Illuminate\\Notifications\\SendQueuedNotifications))
#5 /app/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(227): Illuminate\\Bus\\Dispatcher->pushCommandToQueue(Object(Illuminate\\Queue\\SyncQueue), Object(Illuminate\\Notifications\\SendQueuedNotifications))
#6 /app/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(77): Illuminate\\Bus\\Dispatcher->dispatchToQueue(Object(Illuminate\\Notifications\\SendQueuedNotifications))
#7 /app/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(212): Illuminate\\Bus\\Dispatcher->dispatch(Object(Illuminate\\Notifications\\SendQueuedNotifications))
#8 /app/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(76): Illuminate\\Notifications\\NotificationSender->queueNotification(Array, Object(App\\Notifications\\SomeMessage))
#9 /app/vendor/laravel/framework/src/Illuminate/Notifications/ChannelManager.php(39): Illuminate\\Notifications\\NotificationSender->send(Array, Object(App\\Notifications\\SomeMessage))
#10 /app/vendor/laravel/framework/src/Illuminate/Notifications/RoutesNotifications.php(18): Illuminate\\Notifications\\ChannelManager->send(Object(App\\DingtalkBot), Object(App\\Notifications\\SomeMessage))
#11 /app/routes/web.php(16): App\\DingtalkBot->notify(Object(App\\Notifications\\SomeMessage))
#12 /app/vendor/laravel/framework/src/Illuminate/Routing/Route.php(230): Illuminate\\Routing\\RouteFileRegistrar->{closure}()
#13 /app/vendor/laravel/framework/src/Illuminate/Routing/Route.php(200): Illuminate\\Routing\\Route->runCallable()
#14 /app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(692): Illuminate\\Routing\\Route->run()
#15 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#16 /app/app/Http/Middleware/CheckAccount.php(55): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#17 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\CheckAccount->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#18 /app/app/Http/Middleware/RegisterJPushRegistrationID.php(22): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#19 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\RegisterJPushRegistrationID->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#20 /app/app/Http/Middleware/WithTransaction.php(118): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#21 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\WithTransaction->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#22 /app/app/Http/Middleware/ImpersonateGuard.php(54): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#23 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\ImpersonateGuard->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#24 /app/app/Http/Middleware/SetLocale.php(26): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#25 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\SetLocale->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#26 /app/vendor/itsgoingd/clockwork/Clockwork/Support/Laravel/ClockworkMiddleware.php(24): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#27 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Clockwork\\Support\\Laravel\\ClockworkMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#28 /app/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(41): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#29 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#30 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(77): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#31 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#32 /app/vendor/laravel/framework/src/Illuminate/Session/Middleware/AuthenticateSession.php(58): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#33 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Session\\Middleware\\AuthenticateSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#34 /app/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#35 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#36 /app/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#37 /app/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(63): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest(Object(Illuminate\\Http\\Request), Object(Illuminate\\Session\\Store), Object(Closure))
#38 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Session\\Middleware\\StartSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#39 /app/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#40 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#41 /app/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#42 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#43 /app/app/Http/Middleware/RedirectToAppURL.php(28): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#44 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\RedirectToAppURL->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#45 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#46 /app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(694): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#47 /app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(669): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#48 /app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(635): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#49 /app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(624): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#50 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(166): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#51 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#52 /app/vendor/laravel/nova/src/Http/Middleware/ServeNova.php(26): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#53 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Laravel\\Nova\\Http\\Middleware\\ServeNova->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#54 /app/app/Http/Middleware/SentryContext.php(31): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#55 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\SentryContext->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#56 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#57 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#58 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#59 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#60 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#61 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#62 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(87): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#63 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#64 /app/vendor/fruitcake/laravel-cors/src/HandleCors.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#65 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fruitcake\\Cors\\HandleCors->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#66 /app/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#67 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#68 /app/vendor/itsgoingd/clockwork/Clockwork/Support/Laravel/ClockworkMiddleware.php(24): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#69 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Clockwork\\Support\\Laravel\\ClockworkMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#70 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#71 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(141): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#72 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(110): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#73 /app/public/index.php(52): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#74 {main}
"}
I think I see what's going on. You're using the framework's Illuminate\Queue\Middleware\RateLimited
middleware rather than writing your own as documented here: https://laravel.com/docs/8.x/queues#job-middleware
If you wrote the middleware as documented does the error still happen then?
Just dig into #30070, it seems like NotificationSender@queueNotification
will assign the result of $notification->middleware()
to instance attributes SendQueuedNotifications->$middleware
, which contains an instance of RateLimited
which created by notification's middleware()
method:
public function middleware()
{
return [new RateLimited('notification-channel-xxx')];
}
The RateLimited
instance which contains a named limiter registered in AppServiceProvider
. And the named limiter contains a Closure
, the root cause stopping SendQueuedNotifications
from serialization.
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
RateLimiter::for('notification-channel-xxx', function ($job) {
return Limit::perMinute(20);
});
}
Hmm, I see. I'm not sure what the best solution here would be..
Maybe we can retrieve and instantiate middlewares after the job SendQueuedNotifications
being unserialized, instead of before the serialization. Or maybe registering the named rate limiters in a non-closure way?
Fixed for PHP 7.4+ by this: https://github.com/laravel/framework/commit/f3d4dcb21dc66824611fdde95c8075b694825bf5
@chuangbo can you confirm the commit above fixes your issue? I see you are on PHP 7.4.
@taylorotwell Thank you for the prompt fix! Good to know __serialize
and __unserialize
. By the way, there is a typo I have it fixed: #35916. It feels great to make a tiny contribution to Laravel. Love your work!
I think the same problem is for php 8.x (for me 8.0.6) and Laravel 8.x (for me 8.43.0).
Description:
The notification channel we are using is limiting 20 requests per minute. Since job middleware are supported for queued notifications (#30070), we would like to leverage
Illuminate\Queue\Middleware\RateLimited
middleware for the queued notification, as described in https://laravel.com/docs/8.x/queues#rate-limiting. But it throws exception:Serialization of 'Closure' is not allowed
.Steps To Reproduce:
RateLimiter
in the boot method ofAppServiceProvider