Debugging is part of any developers or even web designer or site administrator. However, some errors and exceptions are really hard to track, as messages are not clear enough.

Error 500 standard page is an example of that. It simply says it found a “server error” and that’s it. It behaves like a software telling you: “ok, I am trying, but your code sucks”. Of course most scripts come with some debugging possibilities, so WordPress does. However, just setting wp-config.php to debug mode not only gives you a clearer message whenever a fatal error happens – it also shows all possible syntax and runtime errors in any file being executed.

That means any mistaken code in any theme or plugin is to return an error message. And believe me: if you are using more than a dozen of plugins, messages will be all over the page. Then, you simply give up and set the debug mode off again.

A native possibility

It’s not common to see anyone using it, but the fact is that WordPress comes with a native way of replacing the typical server error screen. A drop-in, when placed in the wp-content directory, will automatically replace the standard screen in case of any error 500.

If you already noticed, WordPress comes with a custom error 500 page. The problem? It says nothing about the actual problem. It even sends the admin an e-mail informing the site was down, but no hint is given about what the error can actually be.

For having that sorted out, forget about plugins or messing up with Apache2 conf files or the .htaccess file. The only thing you need to do is creating a new template and drop it with a determined name in the wp-content directory.

Beyond a mere custom page

Just having a new glossy page doesn’t help us much, if we need to fix any kind of internal server. Instead, we want this new page to give actionable and clear info about the error or exception that generated the fatal in the first place. In the next few paragraphs, let’s create a simple template which can provide something like the following picture.

So let’s start working in our php-error.php file. The drop-in must have this name, in order to the class WP_Fatal_Error_Handler to find it. First things first – we want our drop-in to be as verbose as possible, but at the same time, we don’t want the typical “one-string” message to come out. So:

error_reporting(E_ALL);
ini_set('display_errors', '1');
ob_clean();

After that, we need to retrieve the last error which generated the error 500. This can be easily done with a simple PHP function. Also, we want to give an OOP aspect to our code, as well as get some few lines from the file where the error appears:

// Returns an array with the last detected error or exception
$error = error_get_last();
// Will show the error message
echo '
Error or Exception:

' . $error['message'] . '

'; // Will show the path to the file that generated the exception echo 'Path of the file:

' . $error['file'] . '

';

Finally, we want to show a few lines of code, highlighting that line indicated by the exception, but also those around it. So let’s make use of range() to create an array of the line numbers we want to read, and then use the SplFileObject class to perform the iteration easily.

$loc = range($error['line'] - 6, $error['line'] + 5);

$where = new SplFileObject($error['file']);
echo '
Source of the exception
';
foreach ($where as $line_num => $line) {
	if(in_array($line_num, $loc)) {
		if((int) $line_num + 1 == $error['line']) {
			echo '' . ((int) $line_num + 1) . ' ' . $line . '';
		} else {
			echo ((int) $line_num + 1) . ' ' . $line . '';
		}
	}
}
echo '
';

Some style on it

Basically, that does the job. However, as we intended to make it more human-friendly, some style on it seems to be essential. Feel free to change it, but encapsulating the PHP part in a HTML/CSS structure, we can have something like this as result:

<?php 
error_reporting(E_ALL);
ini_set('display_errors', '1');
ob_clean();

?>
<!DOCTYPE html>
<html>
<head>
	<title>Human-Friendly Error 500</title>
	<style type="text/css">
		.flexbox {
			display: block;
			margin-left: 20px;
			margin-top: 20px;
		}
		.fixed500 {
			font-size: 1.5em;
			text-transform: uppercase;
			position: fixed;
			bottom: 20px;
			right: 40px;
		}
	</style>
</head>
<body>

<div class="fixed500"><pre>500 Internal Server Error</pre></div>
<div class="flexbox">
<?php

$error = error_get_last();

echo '<div><b>Error or Exception:</b></br><p>' . $error['message'] . '</p>';
echo '<b>Path of the file:</b></br><p>' . $error['file'] . '</p></div>';

$loc = range($error['line'] - 6, $error['line'] + 5);

$where = new SplFileObject($error['file']);
echo '<div><b>Source of the exception</b><pre>';
foreach ($where as $line_num => $line) {
	if(in_array($line_num, $loc)) {
		if((int) $line_num + 1 == $error['line']) {
			echo '<b>' . ((int) $line_num + 1) . ' ' . $line . '</b>';
		} else {
			echo ((int) $line_num + 1) . ' ' . $line . '';
		}
	}
}
echo '</pre></div>';

?>

</div>
</body>
</html>

Leave a comment

Your email address will not be published. Required fields are marked *