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

[2.0] Include SerializesModels in events. #82

Closed
2 of 3 tasks
aon4o opened this issue May 16, 2024 · 1 comment
Closed
2 of 3 tasks

[2.0] Include SerializesModels in events. #82

aon4o opened this issue May 16, 2024 · 1 comment
Assignees
Labels
enhancement New feature or request

Comments

@aon4o
Copy link
Contributor

aon4o commented May 16, 2024

PHP & Platform

8.3.6 - Linux Mint 21.3 Cinnamon x64

Database

MySQL 8.0.32

Laravel version

11.7.0

Have you done this?

  • I have checked my logs and I'm sure is a bug in this package.
  • I can reproduce this bug in isolation (vanilla Laravel install)
  • I can suggest a workaround as a Pull Request

Expectation

Your package has several events.
When I write an event Listener for those, I expect to be able to run the Listeners in a queue like this:

<?php

namespace App\Listeners;

use App\Notifications\TwoFactorRecoveryCodesGeneratedNotification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Laragear\TwoFactor\Events\TwoFactorRecoveryCodesGenerated;

class TwoFactorRecoveryCodesGeneratedListener implements ShouldQueue
{
    use InteractsWithQueue;

    public function handle(TwoFactorRecoveryCodesGenerated $event): void
    {
        // Some logic...
    }
}

In the example code, the ShouldQueue interface and the InteractsWithQueue trait make the listener execute in a queue.

Description

The problem is that the package events don't use the SerializesModels trait which leads to the following problem:
Serialization of 'Closure' is not allowed.

Reproduction

// For reproduction, just make an Event listener for any of the package events.
// The listener must implement `ShouldQueue` and use `InteractsWithQueue`.
// After that dispatch the event and it should result in an exception `Serialization of 'Closure' is not allowed`.

Stack trace & logs

{
  "message": "Serialization of 'Closure' is not allowed",
  "exception": "Exception",
  "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Queue/Queue.php",
  "line": 160,
  "trace": [
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Queue/Queue.php",
      "line": 160,
      "function": "serialize"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Queue/Queue.php",
      "line": 129,
      "function": "createObjectPayload",
      "class": "Illuminate\\Queue\\Queue",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Queue/RedisQueue.php",
      "line": 212,
      "function": "createPayloadArray",
      "class": "Illuminate\\Queue\\Queue",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/horizon/src/RedisQueue.php",
      "line": 86,
      "function": "createPayloadArray",
      "class": "Illuminate\\Queue\\RedisQueue",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Queue/Queue.php",
      "line": 107,
      "function": "createPayloadArray",
      "class": "Laravel\\Horizon\\RedisQueue",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/horizon/src/RedisQueue.php",
      "line": 46,
      "function": "createPayload",
      "class": "Illuminate\\Queue\\Queue",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Queue/Queue.php",
      "line": 59,
      "function": "push",
      "class": "Laravel\\Horizon\\RedisQueue",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php",
      "line": 633,
      "function": "pushOn",
      "class": "Illuminate\\Queue\\Queue",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php",
      "line": 552,
      "function": "queueHandler",
      "class": "Illuminate\\Events\\Dispatcher",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php",
      "line": 478,
      "function": "Illuminate\\Events\\{closure}",
      "class": "Illuminate\\Events\\Dispatcher",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php",
      "line": 286,
      "function": "Illuminate\\Events\\{closure}",
      "class": "Illuminate\\Events\\Dispatcher",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php",
      "line": 266,
      "function": "invokeListeners",
      "class": "Illuminate\\Events\\Dispatcher",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php",
      "line": 453,
      "function": "dispatch",
      "class": "Illuminate\\Events\\Dispatcher",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laragear/two-factor/src/TwoFactorAuthentication.php",
      "line": 205,
      "function": "event"
    },
    {
      "file": "/var/www/html/app/Http/Controllers/API/Admin/ProfileController.php",
      "line": 136,
      "function": "generateRecoveryCodes",
      "class": "App\\Models\\User",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php",
      "line": 46,
      "function": "generateRecoveryCodes",
      "class": "App\\Http\\Controllers\\API\\Admin\\ProfileController",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
      "line": 260,
      "function": "dispatch",
      "class": "Illuminate\\Routing\\ControllerDispatcher",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
      "line": 206,
      "function": "runController",
      "class": "Illuminate\\Routing\\Route",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
      "line": 806,
      "function": "run",
      "class": "Illuminate\\Routing\\Route",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 144,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Router",
      "type": "->"
    },
    {
      "file": "/var/www/html/app/Http/Middleware/Confirm2FAMiddleware.php",
      "line": 28,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 183,
      "function": "handle",
      "class": "App\\Http\\Middleware\\Confirm2FAMiddleware",
      "type": "->"
    },
    {
      "file": "/var/www/html/app/Http/Middleware/PermissionMiddleware.php",
      "line": 48,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 183,
      "function": "handle",
      "class": "App\\Http\\Middleware\\PermissionMiddleware",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/rakutentech/laravel-request-docs/src/LaravelRequestDocsMiddleware.php",
      "line": 49,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 183,
      "function": "handle",
      "class": "Rakutentech\\LaravelRequestDocs\\LaravelRequestDocsMiddleware",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php",
      "line": 50,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 183,
      "function": "handle",
      "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
      "line": 161,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
      "line": 127,
      "function": "handleRequest",
      "class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
      "line": 89,
      "function": "handleRequestUsingNamedLimiter",
      "class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 183,
      "function": "handle",
      "class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php",
      "line": 64,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 183,
      "function": "handle",
      "class": "Illuminate\\Auth\\Middleware\\Authenticate",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php",
      "line": 25,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 144,
      "function": "Laravel\\Sanctum\\Http\\Middleware\\{closure}",
      "class": "Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 119,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php",
      "line": 24,
      "function": "then",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 183,
      "function": "handle",
      "class": "Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 119,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
      "line": 805,
      "function": "then",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
      "line": 784,
      "function": "runRouteWithinStack",
      "class": "Illuminate\\Routing\\Router",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
      "line": 748,
      "function": "runRoute",
      "class": "Illuminate\\Routing\\Router",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
      "line": 737,
      "function": "dispatchToRoute",
      "class": "Illuminate\\Routing\\Router",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
      "line": 200,
      "function": "dispatch",
      "class": "Illuminate\\Routing\\Router",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 144,
      "function": "Illuminate\\Foundation\\Http\\{closure}",
      "class": "Illuminate\\Foundation\\Http\\Kernel",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php",
      "line": 59,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 183,
      "function": "handle",
      "class": "Barryvdh\\Debugbar\\Middleware\\InjectDebugbar",
      "type": "->"
    },
    {
      "file": "/var/www/html/app/Http/Middleware/LocalizationMiddleware.php",
      "line": 44,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 183,
      "function": "handle",
      "class": "App\\Http\\Middleware\\LocalizationMiddleware",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php",
      "line": 121,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php",
      "line": 64,
      "function": "handleStatefulRequest",
      "class": "Illuminate\\Session\\Middleware\\StartSession",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 183,
      "function": "handle",
      "class": "Illuminate\\Session\\Middleware\\StartSession",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
      "line": 21,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php",
      "line": 31,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 183,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
      "line": 21,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php",
      "line": 51,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 183,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php",
      "line": 27,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 183,
      "function": "handle",
      "class": "Illuminate\\Http\\Middleware\\ValidatePostSize",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php",
      "line": 110,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 183,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php",
      "line": 62,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 183,
      "function": "handle",
      "class": "Illuminate\\Http\\Middleware\\HandleCors",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 119,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
      "line": 175,
      "function": "then",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
      "line": 144,
      "function": "sendRequestThroughRouter",
      "class": "Illuminate\\Foundation\\Http\\Kernel",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Application.php",
      "line": 1172,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Kernel",
      "type": "->"
    },
    {
      "file": "/var/www/html/public/index.php",
      "line": 19,
      "function": "handleRequest",
      "class": "Illuminate\\Foundation\\Application",
      "type": "->"
    },
    {
      "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/resources/server.php",
      "line": 16,
      "function": "require_once"
    }
  ]
}
@aon4o aon4o added the bug Something isn't working label May 16, 2024
@aon4o
Copy link
Contributor Author

aon4o commented May 16, 2024

I'm not particularly sure why the problem happens, to be honest.
I tried updating the package's event code to use the SerializesModels trait and my code started working.

I also tried reproducing it in a Vanilla Laravel installation and couldn't do it.
This may be because the User model in my original project is too complex.
It utilizes 10 different traits, attribute functions, scopes, and many more.

But I found this in the Laravel 11 docs:
Events - Defining Events
Queue - Class Structure

These two paragraphs in the documentation make me believe it won't be bad for the package's events to start using the SerializesModels trait.

@DarkGhostHunter DarkGhostHunter added enhancement New feature or request and removed bug Something isn't working labels May 16, 2024
@DarkGhostHunter DarkGhostHunter changed the title [2.0] Exception "Serialization of 'Closure' is not allowed" in event Listeners. [2.0] Include SerializesModels in events. May 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants