Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create and use 404.vue in Inertiajs2 app?

Tags:

inertiajs

How with laravel, Inertiajs2, vuejs3 can I catch invalid url ? If I create file

resources/views/errors/404.blade.php

is it triggered, but I dislike using blade file in this case...

Additive information :

I modified file app/Exceptions/Handler.php

class Handler extends ExceptionHandler {

...
public function render($request, Throwable $e)
{
    $response = parent::render($request, $e);

    // I commented environment checking for development
    if ( /*!app()->environment(['local', 'testing']) &&*/ in_array($response->status(), [500, 503, 404, 403])) {

        // As I want to show separate file for any error I try 404
        return Inertia::render('404', ['status' => $response->status()])
                      ->toResponse($request)
                      ->setStatusCode($response->status());
    } else if ($response->status() === 419) {
        return back()->with([
            'message' => 'The page expired, please try again.',
        ]);
    }

    return $response;
}

I created a file resources/js/Pages/404.vue with lines :

<template>

    <frontend-layout>

        resources/js/Pages/404.vue

    </frontend-layout>


</template>

<script>
import FrontendLayout from '@/Layouts/FrontendLayout'

import {ref, computed, onMounted} from 'vue'
import { defineComponent } from 'vue'

export default defineComponent({
    name: '404Page',
    components: {
        FrontendLayout,
    },
    setup() {
        function HomeOnMounted() {
        } // function HomeOnMounted() {

        onMounted(HomeOnMounted)

        return { // setup return
            // Page state
        }
    }, // setup() {

})
</script>

and I got error :

[2022-05-18 09:52:14] local.ERROR: Uncaught InvalidArgumentException: View [app] not found. in /ProjectPath/vendor/laravel/framework/src/Illuminate/View/FileViewFinder.php:137
Stack trace:
    #0 /ProjectPath/vendor/laravel/framework/src/Illuminate/View/FileViewFinder.php(79): Illuminate\View\FileViewFinder->findInPaths()
#1 /ProjectPath/vendor/laravel/framework/src/Illuminate/View/Factory.php(137): Illuminate\View\FileViewFinder->find()
#2 /ProjectPath/vendor/laravel/framework/src/Illuminate/Routing/ResponseFactory.php(87): Illuminate\View\Factory->make()
#3 /ProjectPath/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(337): Illuminate\Routing\ResponseFactory->view()
#4 /ProjectPath/vendor/inertiajs/inertia-laravel/src/Response.php(113): Illuminate\Support\Facades\Facade::__callStatic()
#5 /ProjectPath/app/Exceptions/Handler.php(52): Inertia\Response->toResponse()
#6 /ProjectPath/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(220): App\Exceptions\Handler->render()
#7 /ProjectPath/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(197): Illuminate\Foundation\Bootstrap\HandleExceptions->renderHttpResponse()
#8 /ProjectPath/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(255): Illuminate\Foundation\Bootstrap\HandleExceptions->handleException()
#9 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->Illuminate\Foundation\Bootstrap\{closure}()
#10 {main}
thrown {"exception":"[object] (Symfony\\Component\\ErrorHandler\\Error\\FatalError(code: 0): Uncaught InvalidArgumentException: View [app] not found. in /ProjectPath/vendor/laravel/framework/src/Illuminate/View/FileViewFinder.php:137
    Stack trace:
        #0 /ProjectPath/vendor/laravel/framework/src/Illuminate/View/FileViewFinder.php(79): Illuminate\\View\\FileViewFinder->findInPaths()
    #1 /ProjectPath/vendor/laravel/framework/src/Illuminate/View/Factory.php(137): Illuminate\\View\\FileViewFinder->find()
    #2 /ProjectPath/vendor/laravel/framework/src/Illuminate/Routing/ResponseFactory.php(87): Illuminate\\View\\Factory->make()
    #3 /ProjectPath/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(337): Illuminate\\Routing\\ResponseFactory->view()
    #4 /ProjectPath/vendor/inertiajs/inertia-laravel/src/Response.php(113): Illuminate\\Support\\Facades\\Facade::__callStatic()
    #5 /ProjectPath/app/Exceptions/Handler.php(52): Inertia\\Response->toResponse()
    #6 /ProjectPath/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(220): App\\Exceptions\\Handler->render()
    #7 /ProjectPath/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(197): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->renderHttpResponse()
    #8 /ProjectPath/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(255): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleException()
    #9 [internal function]: Illuminate\\Foundation\\Bootstrap\\HandleExceptions->Illuminate\\Foundation\\Bootstrap\\{closure}()
    #10 {main}
    thrown at /ProjectPath/vendor/laravel/framework/src/Illuminate/View/FileViewFinder.php:137)
[stacktrace]
#0 /ProjectPath/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(244): Symfony\\Component\\ErrorHandler\\Error\\FatalError->__construct(message: '...', code: '...', error: '...', traceOffset: '...', traceArgs: '...', trace: '...')
#1 /ProjectPath/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(231): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->fatalErrorFromPhpError(error: '...', traceOffset: '...')
#2 /ProjectPath/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(255): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleShutdown()
#3 /ProjectPath/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(0): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->Illuminate\\Foundation\\Bootstrap\\{closure:/ProjectPath/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php:254-256}()
#4 {main}
"} 


as I have 3 layouts (without default app) I have 3 files :
resources/views/layouts/adminlte.blade.php
resources/views/layouts/frontend.blade.php
resources/views/layouts/user.blade.php

and in app/Http/Middleware/HandleInertiaRequests.php I have :

public function rootView(Request $request)
{

    if ($request->segment(1) == 'user') {
        return 'layouts/user';
    }
    if ($request->segment(1) == 'admin') {
        return 'layouts/adminlte'; 
    }

    return 'layouts/frontend'; 
}

I added one more file : /resources/views/layouts/app.blade.php

But I still got error :

 View [app] not found

Looks like all defaults error codes demands standard /resources/views/layouts/app.blade.php file, but why I still got error after I added this file ?

Additive information # 2: Checking provided link I see that file under vendor is used Project/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/views/404.blade.php

If there is a way to copy this file under Project/resources/views/vendor/ and which must be path of this file ?

File resources/js/Pages/error.vue is not opened, even with code in

app/Exceptions/Handler.php :
    return Inertia::render('error', ['status' => $response->status()])
        ->toResponse($request)
        ->setStatusCode($response->status());

Thanks in advance!

like image 212
Petro Gromovo Avatar asked Oct 18 '25 03:10

Petro Gromovo


1 Answers

Error handling is described in the Inertia.js docs.

You need to extend the render() method in your App\Exceptions\Handler.php so it will send a Inertia response back to the client when it hits an error.

It's important to return an Inertia response only in certain scenarios, because doing this will prevent the default Laravel error handling from running and you won't get the useful debug info during development. The code bellow only returns an Inertia response in production.

use Throwable;
use Inertia\Inertia;

/**
 * Prepare exception for rendering.
 *
 * @param  \Throwable  $e
 * @return \Throwable
 */
public function render($request, Throwable $e)
{
    $response = parent::render($request, $e);

    if (!app()->environment(['local', 'testing']) {
        return Inertia::render('Error', ['status' => $response->status()])
            ->toResponse($request)
            ->setStatusCode($response->status());
    }

    return $response;
}
like image 169
Matheus Dal'Pizzol Avatar answered Oct 22 '25 00:10

Matheus Dal'Pizzol