How to: Custom 404 and 500 error pages in Laravel 5.4

Custom 404 error pages

Making a custom 404 error page in Laravel is very simple. All you need to do is make the following file:

resources/views/errors/404.blade.php

That's really all there is to it. It'll just work straight out the box .

How does it work?

If you'd like to know how it works then dive into the frameworks code. Open up the class Illuminate\Foundation\Exceptions\Handler and take a look at the renderHttpException() method.

Essentially, when an error is thrown if it is of the type HttpException then this method will be called and a check will be done first to see if there is an associated view file in your app according to that error's status code. This means this technique will also work for custom 403 error pages. So all you'll need to do is make 403.blade.php and it'll just work.

Custom 500 error pages

Don't be put off by the length of this article, most of it is optional and extra bits. To make a custom 500 error page, all you need to do is open up your app's App\Exceptions\Handler class and write this at the top:

use Symfony\Component\Debug\Exception\FlattenException;

Then add this method at the bottom:

protected function convertExceptionToResponse(Exception $e)
{
	$e = FlattenException::create($e);
	return response()->view('errors.500', ['exception' => $e], $e->getStatusCode(), $e->getHeaders());
}

Then if you wish, you can use the exception variable passed to your view to style the stack trace but most of the time you'll want to hide that on your live environment so I would suggest only showing the basic 500 error page (with no stack trace) on your live environment and then for your dev environment just use the usual method of displaying errors. Let me show you in code:

use App;
use Symfony\Component\Debug\Exception\FlattenException;

// ...

protected function convertExceptionToResponse(Exception $e)
{
	if (App::environment('live'))
	{
		$e = FlattenException::create($e);
		// Just return a basic view. We could use the exception variable we are passing to our view to style the stack trace but why bother? We probably don't want to show that to the user on a live environment anyway.
		return response()->view('errors.500', ['exception' => $e], $e->getStatusCode(), $e->getHeaders());
	}
	
	// If we're on the dev environment then do nothing special, just show the usual error page with stack trace.
	return parent::convertExceptionToResponse($e);
}

If you do insist on styling your stack trace in your custom view file, it might look something like this:

<table>
	<thead>
		<tr>
			<th>Class</th>
			<th>Function</th>
			<th>File</th>
			<th>Line</th>
		</tr>
	</thead>
	<tbody>
@foreach ($exception->getTrace() as $trace)
		<tr>
			<td>{{ $trace['class'] }}</td>
			<td>{{ $trace['function'] }}</td>
			<td>{{ $trace['file'] }}</td>
			<td>{{ $trace['line'] }}</td>
		</tr>
@endforeach
	</tbody>
</table>

How does it work?

Making a custom 500 error page requires a slightly different approach (compared to making the 404 one). The reason for this is because 500 errors are thrown when something has gone wrong in your app, which could be anything. So because any type of exception could've been thrown which may or may not be of the type HttpException (as discussed above), Laravel will just default to using a SymfonyExceptionHandler and SymfonyResponse. You can see the code for this in the aforementioned Handler class under the method convertExceptionToResponse(). So what we are doing instead is overwriting this method and returning everything to our own custom view instead.

0 comments

Comments (0)

Your comment