inertiajs / inertia

Inertia.js lets you quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers.
https://inertiajs.com
MIT License
6.3k stars 423 forks source link

Error handling argument issue #1832

Closed alxmlk closed 6 months ago

alxmlk commented 6 months ago

Version:

Im using default Laravel's auth middleware. When I not authenticated and open a non-existent page, the function works fine - throws 404. But if I open an existing page, it throws:

Issue: Argument ($response) must be of type Illuminate\Http\Response, Illuminate\Http\RedirectResponse given given {"exception":"[object] (TypeError(code: 0): {closure}(): Argument #1 ($response) must be of type Illuminate\Http\Response, Illuminate\Http\RedirectResponse given at \bootstrap\app.php:36)

My bootstrap/app.php:

     ->withRouting(
        web: __DIR__ . '/../routes/web.php',
        commands: __DIR__ . '/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->web(append: [
            \App\Http\Middleware\HandleInertiaRequests::class,
            \Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets::class,
        ]);

        $middleware->alias([
            'is_active' => \App\Http\Middleware\ForbiddenIfNotActive::class,
            'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
            'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
            'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
        ]);

        $middleware->redirectTo(
            guests: '/',
            users: '/dashboard'
        );
    })
    ->withExceptions(function (Exceptions $exceptions) {
        $exceptions->respond(
            function (Response $response, Throwable $exception, Request $request) {
                if (in_array($response->status(), [500, 503, 404, 403])) {
                    return Inertia::render('Error', ['status' => $response->status()])
                        ->toResponse($request)
                        ->setStatusCode($response->status());
                } elseif ($response->status() === 419) {
                    return back()->with([
                        'message' => 'The page expired, please try again.',
                    ]);
                }

                return $response;
            }
        );

ForbiddenIfNotActive middleware:

    public function handle(Request $request, Closure $next): Response
    {

        if ($request->user()->is_active) return $next($request);

        abort(403);
    }

Everything else is standard.

DashboardController

class DashboardController extends Controller  implements HasMiddleware
{
    /**
     * Get the middleware that should be assigned to the controller.
     */
    public static function middleware(): array
    {
        return [
            'auth', 'is_active', 'role:admin|editor'
        ];
    }

    /**
     * Display the view.
     */
    public function index()
    {
        return Inertia::render('Dashboard');
    }
}

What could be the problem or what am I doing wrong?

alxmlk commented 6 months ago

Solved issue by changing imports:

use Illuminate\Http\Request -> use Symfony\Component\HttpFoundation\Request; use Illuminate\Http\Response -> use Symfony\Component\HttpFoundation\Response;

And change function status() to getStatusCode();

 $exceptions->respond(
            function (Response $response, Throwable $exception, Request $request) {
                if (! app()->environment(['local', 'testing']) && in_array($response->getStatusCode(), [500, 503, 404, 403])) {
                    return Inertia::render('Error', ['status' => $response->getStatusCode()])
                        ->toResponse($request)
                        ->setStatusCode($response->getStatusCode());
                } elseif ($response->getStatusCode() === 419) {
                    return back()->with([
                        'message' => 'The page expired, please try again.',
                    ]);
                }

                return $response;
            }
        );