64

In Laravel 5, App::missing and App::error is not available, so how do your catch exceptions and missing pages now?

I could not find any information regarding this in the documentation.

Marwelln
  • 28,492
  • 21
  • 93
  • 117

8 Answers8

96

In Laravel 5 you can catch exceptions by editing the render method in app/Exceptions/Handler.php.

If you want to catch a missing page (also known as NotFoundException) you would want to check if the exception, $e, is an instance of Symfony\Component\HttpKernel\Exception\NotFoundHttpException.

public function render($request, Exception $e) {
    if ($e instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException)
        return response(view('error.404'), 404);

    return parent::render($request, $e);
}

With the code above, we check if $e is an instanceof of Symfony\Component\HttpKernel\Exception\NotFoundHttpException and if it is we send a response with the view file error.404 as content with the HTTP status code 404.

This can be used to ANY exception. So if your app is sending out an exception of App\Exceptions\MyOwnException, you check for that instance instead.

public function render($request, Exception $e) {
    if ($e instanceof \App\Exceptions\MyOwnException)
        return ''; // Do something if this exception is thrown here.

    if ($e instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException)
        return response(view('error.404'), 404);

    return parent::render($request, $e);
}
Marwelln
  • 28,492
  • 21
  • 93
  • 117
  • 4
    How did you know this answer, where can I find more information about this? – Aditya M P Feb 18 '15 at 07:00
  • @adityamenon, it was for previous development version of Laravel 5. I've rewritten it to match current version of Laravel 5. – Marwelln Feb 18 '15 at 10:29
  • 2
    Aditya Menon, the basics of the Handler.php and the render() function are explained in the docs at http://laravel.com/docs/5.0/errors (but Marwelln's answer is a good example of how to use it). – orrd Feb 27 '15 at 05:56
  • @adityamenon I tried to use your approach, but I struggle to find the correct naming for the `instanceof`, could you perhaps give me a hint. Heres my issue: http://stackoverflow.com/questions/32034259/twilio-catching-error-does-not-work – jerik Aug 17 '15 at 10:09
  • Can anyone check that this handles the TokenMismatchException? I can't get it to on my setup and I've no clue as to why. All docs and examples suggest it should be passed through the `App\Exceptions\Handler::render()` method – simonhamp Dec 16 '15 at 09:41
16

With commit from today (9db97c3), all you need to do is add a 404.blade.php file in the /resources/views/errors/ folder and it will find and display it automatically.

  • 1
    This works for all Http error code responses as of 5.0.1. So you can have custom views for 500, 401, 403 ect. – Joe Feb 18 '15 at 10:37
4

Since commits 30681dc and 9acf685 the missing() method had been moved to the Illuminate\Exception\Handler class.

So, for some time, you could do this:

app('exception')->missing(function($exception)
{
    return Response::view('errors.missing', [], 404);
});


... But then recently, a refactoring has been done in 62ae860.

Now, what you can do is adding the following to app/Http/Kernel.php:

// add this...
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Response;

class Kernel extends HttpKernel {

    (...)

    public function handle($request)
    {
        try
        {
            return parent::handle($request);
        }

        // ... and this:
        catch (NotFoundHttpException $e)
        {
            return Response::view('errors.missing', [], 404);
        }

        catch (Exception $e)
        {
            throw $e;
        }
    }


Finally, please keep in mind Laravel is still under heavy development, and changes may occur again.

Gras Double
  • 15,901
  • 8
  • 56
  • 54
3

In case you want to keep the handler in your web routes file, after your existing routes:

Route::any( '{all}', function ( $missingRoute) {
    // $missingRoute
} )->where('all', '(.*)');
S..
  • 5,511
  • 2
  • 36
  • 43
2

Angular HTML5 mode could cause a bunch of missing pages (user bookmark few page and try to reload). If you can't override server settings to handle that, you might thinking of override missing page behaviour.

You can modify \App\Exceptions\Handler render method to push content with 200 rather than push 404 template with 404 code.

/**
 * Render an exception into an HTTP response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Exception  $e
 * @return \Illuminate\Http\Response
 */
public function render($request, Exception $e)
{
    if ($this->isHttpException($e) && $e->getStatusCode() == 404)
    {
        return response()->view('angular', []);
    }
    return parent::render($request, $e);
}
Sándor Tóth
  • 743
  • 4
  • 10
1

Laravel ships with default error page, You can easily add custom error pages like this

1 - Create an error view in view -> errors folder
2 - The name must match HTTP errors like 404 or 403 500

`Route::get('/page/not/found',function($closure){
  // second param is  optional 
  abort(404, 'Page Not found');
});`
mdamia
  • 4,447
  • 1
  • 24
  • 23
0

By Adding following code

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

and

public function render($request, Exception $e)
    {
    return redirect('/');
            //return parent::render($request, $e);
    }

will work properly for me

A J
  • 3,970
  • 14
  • 38
  • 53
Swapnil Bijwe
  • 347
  • 2
  • 7
-1

One way you can handle it but it's not the best is to change over to a redirect.

<?php namespace App\Exceptions;

use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler {

        /**
         * A list of the exception types that should not be reported.
         *
         * @var array
         */
        protected $dontReport = [
                'Symfony\Component\HttpKernel\Exception\HttpException'
        ];

        /**
         * Report or log an exception.
         *
         * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
         *
         * @param  \Exception  $e
         * @return void
         */
        public function report(Exception $e)
        {
                return parent::report($e);
        }

        /**
         * Render an exception into an HTTP response.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Exception  $e
         * @return \Illuminate\Http\Response
         */
        public function render($request, Exception $e)
        {
        return redirect('/');
                //return parent::render($request, $e);
        }

}
Ulfalizer
  • 4,664
  • 1
  • 21
  • 30
segFault42
  • 17
  • 5