Custom WordPress database error pages

WordPress 2.3.2 introduced a nice new feature which has been on my todo list for quite a while, and I’ve now finally gotten around to: the possibility to create a custom database error page. The idea is simple, you upload a file called db-error.php to your wp-content directory, and that file will be shown when the database connection fails. There’s a few neat things you can do with that, and some things you should keep in mind.

Quite a few blogs have already discussed this feature, and they all forgot one thing (that is not properly documented anywhere, so you can’t really blame them): their error pages don’t give an HTTP 500 Internal Server Error header, but a normal “200 OK” header. If you do nothing, the default WordPress error page does give an error 500, but the db-error.php page doesn’t. This means that should your database fail, and someone would open your front page at example.com, he would be served that error page with a 200 OK header. If that someone were a search engine, that’s what it would index… If the search engine encounters a 500 error, it will not index that page and just wait for your server to be fixed again. That means not making sure it sends a 500 header is a huge risk.

The fix is simple, you just add a single line to your db-error page:

header("HTTP/1.0 500 Internal Server Error");

Now once you have this error page, there’s all sorts of cool things you can do. For instance, I made my error page send out an email to me first, so I can’t miss it when my database fails. The code for that is quite simple:

$mailto 	= "Joost de Valk <no @spamfor.me>";
$mailfrom 	= "no@spamfor.me";
if ($_SERVER['REQUEST_URI'] != "/wp-content/db-error.php") {
	$headers 	= "From: ".$mailfrom."rn".
			  "X-Mailer: PHP/".phpversion()."rn".
			  "X-Priority: 1 (High)";
	$message	= "Go fix it!nn".
			  "It broke when someone tried to open this page: 

http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']."nn".

			  "Best,n".
			  "Your WordPress installation";
	$subject	= "DB error at ".$_SERVER['SERVER_NAME'];
	mail($mailto,$subject,$message,$headers);
}</no>

You could of course also make it send you a text message, or other fancy things, but then you might want to build in some frequency capping. The 500 header goes below the piece of code above by the way, you might get a “headers already sent” error otherwise. Below that you can just put a static HTML page. Some people advice you to use get_header() and get_footer(), but if there’s no database connection, WordPress doesn’t know what theme it should use. So just copy the code in your header.php, single.php and footer.php and strip out all WordPress stuff, and put that below the code above, and you should be good.

Yoast.com runs on the Genesis Framework

Genesis theme frameworkThe Genesis Framework empowers you to quickly and easily build incredible websites with WordPress. Whether you're a novice or advanced developer, Genesis provides you with the secure and search-engine-optimized foundation that takes WordPress to places you never thought it could go.

Read our Genesis review or get Genesis now!

17 Responses

  1. MarkusBy Markus on 10 March, 2008

    Hello Joost

    I think, the db_error.php is for the user who visit my blog. They don’t see the header status code except with special tools.

    But you’re right to send a 500. I didn’t notice that until now, but the robots will read the header, and I don’t want to find my db_error in the google search results.

    So thanks for the tip, I will use it.

    The idea sending a mail has grown up in me too, but I leave it. On my shared hosting web space I’m not able to do anything, when an db error occurs.

    Best regeards from Germany,
    Markus

  2. Mark van EijkBy Mark van Eijk on 10 March, 2008

    I would like to comment that you should use $_SERVER['HTTP_HOST'] instead of $_SERVER['SERVER_NAME']. Because your version takes the actual servername (this could be s001.yourhost.nl) and you’re domainname is actually inside HTTP_HOST. So this will make your e-mail much more clearer when you’ve got more than one website.

  3. Joost de ValkBy Joost de Valk on 10 March, 2008

    Hmm Mark, I tested that, and for me it contained my server name just right this way…

  4. Mark van EijkBy Mark van Eijk on 10 March, 2008

    HTTP_HOST takes the name of the host you request. So in this case this would be joostdevalk.nl. When you use SERVER_NAME it takes the name of the server your webhost uses as their hostname for the webserver.

  5. Joost de ValkBy Joost de Valk on 10 March, 2008

    hmm depends on your apache config then I guess, I run 30odd websites on that server and it works correctly with this code on all of them…

  6. WPModderBy WPModder on 11 March, 2008

    Great tip Joost, thank you so much for sharing!

  7. MarkusBy Markus on 11 March, 2008

    Hello Joost

    I just tried out this tip, and it is good when calling the error page directly. The web developer in Firefox showed me the 500 header.

    Now I changed the wp-config.php for a few seconds to raise a real db error, but then the error page comes with 200 OK.

  8. Joost de ValkBy Joost de Valk on 12 March, 2008

    will test that tonight Marcus, thx!

  9. [BLT]FQXBy [BLT]FQX on 6 April, 2008

    So what is the test result, Joost?
    Since your time stamp says it’s Mar 12, but I received the pingback on Apr 6.

  10. PashalexBy Pashalex on 10 April, 2008

    I am trying to install a new theme in word press 2.o but any theme i chose it comes up with an error “Broken Theme” and “style.css is unreadable”.
    Any comments much appreciated.

  11. CantStopTheSignalBy CantStopTheSignal on 3 June, 2008

    Why can’t cached pages be shown in lieu of error pages, if they exist? There’s a perfectly good copy of the page in cache, why show an error page?

    The wp-cache engine would just need to include a comment tag in the html source that a database error occured and the page is from cache. If the cache is expired, then show it anyway, but also output the 500 header. Otherwise 200 header if the page isn’t otherwise expired.

    Only if there is no cached page for the request would I want to have an error page to appear when the database is not accessible.

    This feature would wildly make WP capable of high-availability in high traffic situations.

  12. AkshayBy Akshay on 21 August, 2008

    sir, i have made a blog recently http://charismatic-verma.blogspot.com/. What should i do to make it adsense frindly and to increase it’s pr, suggestions needed.

Trackbacks

  1. [...] Custom WordPress database error pages: This is an interesting article on how to setup WordPress to display custom database error pages and even send out an email to the owner of the blog in case of database failure. This means that should your database fail, and someone would open your front page at example.com, he would be served that error page with a 200 OK header. If that someone were a search engine, that’s what it would index… If the search engine encounters a 500 error, it will not index that page and just wait for your server to be fixed again. That means not making sure it sends a 500 header is a huge risk. « I am really loving Safari for Windows [...]