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

RunwayRoutes trait throws a "Maximum call stack size" exception #420

Closed
cworreschk opened this issue Feb 1, 2024 · 8 comments · Fixed by #429
Closed

RunwayRoutes trait throws a "Maximum call stack size" exception #420

cworreschk opened this issue Feb 1, 2024 · 8 comments · Fixed by #429

Comments

@cworreschk
Copy link

Description

If a model uses the trait RunwayRoutes, an existing (also a not existing) attribute slug cannot be accessed without crashing the entire application.

With PHP 8.2.15 the application simply exits without an error message.

With PHP 8.3.0 the exception Error Maximum call stack size of 8355840 bytes reached. Infinite recursion? is displayed.

image

Steps to reproduce

  1. Install a fresh new Statamic project with the latest version 4.47.0
  2. Install the latest statamic-rad-pack/runway package with composer (6.0.5)
  3. Add the RunwayRoutes trait to the existing User model
  4. Start Tinker and instantiate a new user with $user = new App\Models\User()
  5. Call $user->slug

Environment

Environment
Application Name: Statamic
Laravel Version: 10.43.0
PHP Version: 8.2.15 / 8.3.0
Composer Version: 2.5.5
Environment: local
Debug Mode: ENABLED
URL: statamic-runway.test
Maintenance Mode: OFF

Cache
Config: NOT CACHED
Events: NOT CACHED
Routes: NOT CACHED
Views: NOT CACHED

Drivers
Broadcasting: log
Cache: statamic
Database: mysql
Logs: stack / single
Mail: smtp
Queue: sync
Session: file

Statamic
Addons: 1
Antlers: runtime
Stache Watcher: Enabled
Static Caching: Disabled
Version: 4.47.0 Solo

Statamic Addons
statamic-rad-pack/runway: 6.0.5

@cworreschk cworreschk added the bug label Feb 1, 2024
@duncanmcclean
Copy link
Member

Are you using the {{ nocache }} tag anywhere?

@cworreschk
Copy link
Author

cworreschk commented Feb 2, 2024

No, I'm not using any {{ nocache }} tag.

I'm using Laravel Herd and installed with the statamic/cli a fresh new Statamic project. The only installed Addon is statamic-rad-pack/runway.

Without configurating anything I've created a new Model with only these lines of code:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use StatamicRadPack\Runway\Routing\Traits\RunwayRoutes;
use StatamicRadPack\Runway\Traits\HasRunwayResource;

class Dog extends Model {
    use HasRunwayResource, RunwayRoutes;
}

The runway configuration has only one resource:

<?php

return [
    'resources' => [
        App\Models\Dog::class => [
            'name'        => 'Dogs',
            'route'       => '/dogs/{{ slug }}',
            'template'    => 'dogs/show',
        ],
    ],
    'disable_migrations' => true,
];

I open Tinker straight after that:
image

After I've removed the RunwayRoutes trait, I'm getting a null as expected:
image

@duncanmcclean
Copy link
Member

What does your migration look like? Do you have a slug column?

@cworreschk
Copy link
Author

In my real project I do have a slug column, but here in my example with the freshly created Statamic project and the Dog class, there is no migration. But in both cases I'm getting the exception.

@duncanmcclean
Copy link
Member

Do you get the same error when creating models with the Dog::create([]) syntax?

@cworreschk
Copy link
Author

If I try to create the Dogmodel with Dog::create([]) then I get a different error:
image

I've tested it now with Laravel Sail, to check if Laravel Herd is the problem. But the same exception 😞

It's really strange. Especially as it's a completely fresh Statamic installation.

@cworreschk
Copy link
Author

After some tests I found out that the exception only occurs if the slug is unset. If it has a value, everything's fine.

In my case the user has the possibility to set the slug manually. If it's not set, in the life cycle event creating the value is generated by another field, e.g. title.

But the content of the slug field cannot be checked, because if it's empty, the exception is thrown.

I have to use this workaround: Get all attributes with toArray() or getAttributes() and check if the slug is set 🙃

@duncanmcclean
Copy link
Member

duncanmcclean commented Feb 10, 2024

Thanks for doing some digging!

Runway's RunwayRoutes trait contains a slug() method (which is required by Statamic's routing contracts).

The slug method attempts to get the current slug for the model, using Eloquent's getAttribute method. Since, it can't find a value for slug on the model, it finds that there's a slug() method on the model and tries to use that instead. That's where the infinite loop happens.

We do need the slug method in the RunwayRoutes method or the feature wouldn't work at all. However, it obviously needs to be re-worked to avoid the infinite loop. I'll have a think about the best way to fix this 🤔

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

Successfully merging a pull request may close this issue.

2 participants