Custom error page not showing on Laravel 5

2019-01-26 10:18发布

问题:

I am trying to display a custom error page instead of the default Laravel 5 message :

"Whoops...looks like something went wrong"

I made a lot of search before posting here, I tried this solution, which should work on Laravel 5 but had no luck with it : https://laracasts.com/discuss/channels/laravel/change-whoops-looks-like-something-went-wrong-page

Here is the exact code I have in my app/Exceptions/Handler.php file :

<?php namespace App\Exceptions;

use Exception;
use View;
use Bugsnag\BugsnagLaravel\BugsnagExceptionHandler as ExceptionHandler;

class Handler extends ExceptionHandler {

    protected $dontReport = [
        'Symfony\Component\HttpKernel\Exception\HttpException'
    ];

    public function report(Exception $e)
    {
        return parent::report($e);
    }

    public function render($request, Exception $e)
    {
        return response()->view('errors.defaultError');
    }

}

But, instead of displaying my custom view, a blank page is showing. I also tried with this code inside render() function

return "Hello, I am an error message";

But I get same result : blank page

回答1:

Instead of the response create a route for your error page in your Routes.php, with the name 'errors.defaultError'. for example

route::get('error', [
    'as' => 'errors.defaultError',
    'uses' => 'ErrorController@defaultError' ]);

Either make a controller or include the function in the route with

return view('errors.defaultError');

and use a redirect instead. For example

public function render($request, Exception $e)
{
    return redirect()->route('errors.defaultError');
}


回答2:

I strongly agree with everyone who wants to customize the error experience in Laravel such that their users never see an embarrassing message such as 'Whoops, looks like something went wrong.'

It took me forever to figure this out.

How To Customize the "Whoops" Message In Laravel 5.3

In app/Exceptions/Handler.php, replace the entire prepareResponse function with this one:

protected function prepareResponse($request, Exception $e)
{        
    if ($this->isHttpException($e)) {            
        return $this->toIlluminateResponse($this->renderHttpException($e), $e);
    } else {
        return response()->view("errors.500", ['exception' => $e]); //By overriding this function, I make Laravel display my custom 500 error page instead of the 'Whoops, looks like something went wrong.' message in Symfony\Component\Debug\ExceptionHandler
    }
}

Basically, it's almost identical to the original functionality, but you're just changing the else block to render a view.

In /resources/views/errors, create 500.blade.php.

You can write whatever text you want in there, but I always recommend keeping error pages very basic (pure HTML and CSS and nothing fancy) so that there is almost zero chance that they themselves would cause further errors.

To Test That It Worked

In routes/web.php, you could add:

Route::get('error500', function () {
    throw new \Exception('TEST PAGE. This simulated error exception allows testing of the 500 error page.');
});

Then I would browse to mysite.com/error500 and see whether you see your customized error page.

Then also browse to mysite.com/some-nonexistent-route and see whether you still get the 404 page that you've set up, assuming you have one.



回答3:

on Larvel 5.2 on your app/exceptions/handler.php just extend this method renderHttpException ie add this method to handler.php customize as you wish

/**
 * Render the given HttpException.
 *
 * @param  \Symfony\Component\HttpKernel\Exception\HttpException  $e
 * @return \Symfony\Component\HttpFoundation\Response
 */
protected function renderHttpException(HttpException $e)
{

   // to get status code ie 404,503
    $status = $e->getStatusCode();

    if (view()->exists("errors.{$status}")) {
        return response()->view("errors.{$status}", ['exception' => $e], $status, $e->getHeaders());
    } else {
        return $this->convertExceptionToResponse($e);
    }
}


回答4:

In laravel 5.4, you can place this code block inside render function in Handler.php - found in app/exceptions/Handler.php

  //Handle TokenMismatch Error/session('csrf_error')
    if ($exception instanceof TokenMismatchException) {
        return response()->view('auth.login', ['message' => 'any custom message'] );
    }

    if ($this->isHttpException($exception)){       
        if($exception instanceof NotFoundHttpException){
            return response()->view("errors.404");
        }
        return $this->renderHttpException($exception);
    }

    return response()->view("errors.500");
    //return parent::render($request, $exception);


回答5:

I have two error pages - 404.blade.php & generic.blade.php

I wanted:

  • 404 page to show for all missing pages
  • Exception page for exceptions in development
  • Generic error page for exceptions in production

I'm using .env - APP_DEBUG to decide this.

I updated the render method in the exception handler:

app/Exceptions/Handler.php

public function render($request, Exception $e)
{
    if ($e instanceof ModelNotFoundException) {
        $e = new NotFoundHttpException($e->getMessage(), $e);
    }

    if ($this->isUnauthorizedException($e)) {
        $e = new HttpException(403, $e->getMessage());
    }

    if ($this->isHttpException($e)) {
        // Show error for status code, if it exists
        $status = $e->getStatusCode();
        if (view()->exists("errors.{$status}")) {
            return response()->view("errors.{$status}", ['exception' => $e], $status);
        }
    }

    if (env('APP_DEBUG')) {
        // In development show exception
        return $this->toIlluminateResponse($this->convertExceptionToResponse($e), $e);
    }
    // Otherwise show generic error page
    return $this->toIlluminateResponse(response()->view("errors.generic"), $e);

}


回答6:

The typical way to do this is to just create individual views for each error type.

I wanted a dynamic custom error page (so all errors hit the same blade template).

In Handler.php I used:

public function render($request, Exception $e)
{
    // Get error status code.
    $statusCode = method_exists($e, 'getStatusCode') ? $e->getStatusCode() : 400;
    $data = ['customvar'=>'myval'];
    return response()->view('errors.index', $data, $statusCode);
}

Then I don't have to create 20 error pages for every possible http error status code.