Nate Northway

Error Handling and HTTP Redirects

blog | January 24, 2017

Default Apache Error Page

There are few things I dislike more than seeing a website handle basic errors with a default error page. There are a few UI/X considerations to think about when handling redirects to tell the user they've encountered an error. The case I think about most often includes a user being linked to a page that no longer exists. A default page will tell them only that the page doesn't exist. It won't tell the user if (a) the site also no longer exists, (b) if the page exists elsewhere, or (c) how to find what they're looking for. Additionally, the default error page gives no easy way to navigate to the rest of the site. It doesn't include a search form to look for the content they tried to access, nor does it provide a way to find out if the link they were given just had a typo.

How I Fix This

There are a lot of ways to deal with HTTP redirects. The way I do it is with Apache - your server's configuration may be a little different if you're on a different platform.(*) Basically, I tell my server that if there is an HTTP error, to redirect to a certain page, called error.php, in the root directory of my site.

...
ErrorDocument 400 /error.php
ErrorDocument 403 /error.php
ErrorDocument 404 /error.php
ErrorDocument 405 /error.php
ErrorDocument 408 /error.php
ErrorDocument 500 /error.php
ErrorDocument 502 /error.php
ErrorDocument 504 /error.php
...

This custom page has two main components: a variable to store the redirect type (from $_SERVER['REDIRECT_STATUS']) and a keyed array with the codes set as the key and values being an array with one value for the name of the code and another value with the description.

$status = $_SERVER['REDIRECT_STATUS'];
$codes = array(
  400 => array('400 Bad Request', 'The request cannot be fulfilled due to bad syntax.'),
  403 => array('403 Forbidden', 'The server has refused to fulfill your request.'),
  404 => array('404 Not Found', 'The page you requested was not found on this server'),
  405 => array('405 Method Not Allowed', 'The method specified in the request is not allowed for the specified resource.'),
  408 => array('408 Request Timeout', 'Your browser failed to send a request in the time allowed by the server.'),
  500 => array('500 Internal Server Error', 'The request was unsuccessful due to an unexpected condition encountered by the server.'),
  502 => array('502 Bad Gateway', 'The server received an invalid response while trying to carry out the request.'),
  504 => array('504 Gateway Timeout', 'The upstream server failed to send a request in the time allowed by the server.'),
);

I use the template of my site's index.html file to import the necessary styles and code, then hit the user with a full page message, explaining, in detail, the code and nature of the error. I add in a few actions they can take, too: go back to where they came from or search for what they were looking for. I use jQuery to get the last URL (if there is one), and set the link on the page to it. I also change the link text depending on if it was a referred link or not.

  if (document.referrer && $("#btn").length) {
    $("#btn").attr("href", document.referrer);
    $("#btn").text("Go Back");
  } else {
    $("#btn").attr("href", "index.html");
    $("#btn").text("Go Home");
  }

The HTML is really simple. I'll omit the <head> and just leave you with the main section

<div class='error' id='redirect'>
    <h1>Error: <?php echo $codes[$status][0]; ?></h1>
    <p class='lead'>
      <?php echo $codes[$status][1]; ?>
    </p>
    <a class='dg-close' href='' id='btn'></a>
    <div class='row center-align'>
        <form role='search' method='get' id='searchform' class='searchform' action='searchform.php'>
            <h3>Try A Search</h3>
            <div class='input-field'>
                <label class='screen-reader-test' for='s'>Search For:</label>
                <input type='text' name='s' id='s' />
                <input type='submit' name='submit' value='Search' class='dg-close' />
            </div>
        </form>
    </div>
</div>

There are different (and arguably better) ways to do this, but this is how I handle HTTP redirects to provide a consistent UI and give the user more information than just "There was an error". This solution solves 2/3 problems presented: it tells the user the site exists (just by being a non-default page), and it shows the user how to find what they're looking for. (The functionality to suggest pages will be in another post.)
A little extra thing that can be done: in 'error.php', a short bit can be added to email yourself a an error report, including the URL that triggered it, the redirect status and code, and any other relevant information.

Want to see this in action? Click here to throw an error.

* If you'd like to provide different language samples, I'd love to include them! Just shoot me an email!

Reply

Your email address will not be published.All Fields Are Required

< Previous Post: Development Software and ToolsNext Post: Net Neutrality: What it Is, Why it Matters, and How it Concerns You >