laravel-json-api / laravel

JSON:API for Laravel applications
MIT License
551 stars 42 forks source link

ExceptionParser - $request->route() is null | line:249 #204

Closed catabozan closed 2 years ago

catabozan commented 2 years ago

Laravel: 9 laravel-json-api: 2.4

I have implemented some API endpoints to my app that also has web routes.

The problem occurs when visiting non-existing web routes: instead of getting the 404 not found page, I get a blank page with a 500 response. The problem occurs in laravel-json-api/exceptions/src/ExceptionParser::acceptsMiddleware on line 249.

 public function acceptsMiddleware(...$middleware): self
    {
        $this->accept[] = static fn($ex, $request): bool => Collection::make($middleware)
            ->intersect($request->route()->gatherMiddleware()) // <- here
            ->isNotEmpty();

        return $this;
    }

Because $request->route() returns null.

I recently installed the stancl/tenancy package that adds multitenancy to my app, and divides the routes into central routes (available without being a tenant), and tenancy routes. I don't know if this is relevant but the stancl/tenancy package adds its own middleware before all other middleware. The weird part is that if for example I have a tenant specific route (let's say /home) and I try to access it without being in a tenant context, I get the 404 error (correct behavior). But if I try to access a route that is not defined as a tenant nor domain specific route (it does not exist anywhere), I get the error mentioned above.

Is this a package related problem?

Maybe change the acceptsMiddleware() method like this

 public function acceptsMiddleware(...$middleware): self
    {
        $this->accept[] = static fn($ex, $request): bool => Collection::make($middleware)
            ->intersect($request->route()?->gatherMiddleware() ?? Collection::make([])) // 249
            ->isNotEmpty();

        r

Or is there something wrong with my setup?

If this is the case, do you know what could be the cause of the issue, or where should I ask for help?

This is in my RouteServiceProvider:

public function boot(): void
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::prefix('api')
                ->middleware(['api', 'force.json'])
                ->namespace($this->namespace)
                ->group(base_path('routes/api.php')); // jsonapi routes

            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/web/tenant.php')); // tenant specific routes
        });

        $this->mapCentralRoutes(); // non-tenant specific routes (central)
        $this->mapUniversalRoutes(); // shared routes between tenancy and non-tenancy context
    }

protected function mapCentralRoutes(): void
    {
        foreach (config('tenancy.central_domains', []) as $domain) {
            Route::middleware('web')
                ->domain($domain)
                ->namespace($this->namespace)
                ->group(base_path('routes/web/central.php'));
        }
    }

protected function mapUniversalRoutes(): void
    {
        Route::middleware('web')
            ->namespace($this->namespace)
            ->group(base_path('routes/web/universal.php'));
    }
lindyhopchris commented 2 years ago

Looks like a bug - if the request's route() method can return null, we should handle that gracefully rather than causing another error. Thanks for reporting.

lindyhopchris commented 2 years ago

Tagged the laravel-json-api/exceptions package with the fix as v1.1.1.

lindyhopchris commented 2 years ago

To upgrade:

composer up laravel-json-api/*