Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Custom WordPress Error Pages (not 404; this one is handled via your theme): A php snippet to put in your functions.php or in your plugin to get rid of the default WP error pages and have custom ones that match with your theme. The code is taken from a CRM application I'm building on top of WordPress [personal project] and slightly modified to be…
add_filter( 'wp_die_handler', 'nc_get_custom_error_handler' );
function nc_get_custom_error_handler() {
return 'nc_custom_error_handler';
function nc_custom_error_handler( $message, $title = '', $args = array() ) {
$defaults = array( 'response' => 500, 'back_link' => false );
$r = wp_parse_args($args, $defaults);
$have_gettext = function_exists('__');
if ( is_string( $message ) ) {
$message = "<p>$message</p>";
elseif ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) {
if ( empty( $title ) ) {
$error_data = $message->get_error_data();
if ( is_array( $error_data ) && isset( $error_data['title'] ) )
$title = $error_data['title'];
$errors = $message->get_error_messages();
switch ( count( $errors ) ) {
case 0 :
$message = '';
case 1 :
$message = "<p>{$errors[0]}</p>";
default :
$message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $errors ) . "</li>\n\t</ul>";
else {
$message = "<h1>Bummer!</h1><p>Something went wrong and we are trying to figure it out. Check back soon!</p>"; //add your own default message
if ( isset( $r['back_link'] ) && $r['back_link'] ) {
$back_text = $have_gettext? __('&laquo; Go Back') : '&laquo; Go Back';
$message .= "\n<p><a href='javascript:history.back()'>$back_text</a></p>";
if ( ! did_action( 'admin_head' ) ) :
if ( !headers_sent() ) {
status_header( $r['response'] );
header( 'Content-Type: text/html; charset=utf-8' );
if ( empty($title) )
$title = $have_gettext ? __('Huston we have a problem!') : 'Huston we have a problem'; //add your own default title
$text_direction = 'ltr';
if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] )
$text_direction = 'rtl';
elseif ( function_exists( 'is_rtl' ) && is_rtl() )
$text_direction = 'rtl';
<!DOCTYPE html>
<!-- You might need to add a few random characters in a comment if your html outputs a file less than 512 bytes (even if gzipped). : IE bug -->
<html xmlns="" <?php if ( function_exists( 'language_attributes' ) && function_exists( 'is_rtl' ) ) language_attributes(); else echo "dir='$text_direction'"; ?>>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><?php echo $title ?></title>
<style type="text/css">
/** You'll need to alter with your own styles of course **/
html {
background: #C8AEE8;
#error-page {
font-family: Helvetica, Arial, sans-serif;
color: #314E55;
margin: 50px auto;
padding: 5% auto;
.error-content {
background: #fff;
margin: auto;
max-width: 630px;
border-radius: 15px;
-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.13);
box-shadow: 0 1px 3px rgba(0,0,0,0.13);
.error-content *::selection {
color: #fff;
background: #73C9C9;
.error-content *::-moz-selection {
color: #fff;
background: #73C9C9;
.error-content p,
.error-content ul {
font-size: 1em;
line-height: 1.5;
padding: 0 26px 26px;
.error-content ul {
margin-left: 26px;
.error-content ul li {
margin-bottom: 10px;
.error-content ul li:last-child {
margin-bottom: 0;
.error-content h1 {
font-size: 1.8em;
padding: 26px 26px 0;
text-align: center;
a {
color: #73C9C9;
text-decoration: none;
a:hover {
color: #314E55;
.button {
background: #73C9C9;
border: 1px solid #73C9C9;
color: #fff;
display: inline-block;
text-decoration: none;
cursor: pointer;
-webkit-border-radius: 5px;
-webkit-appearance: none;
border-radius: 5px;
white-space: nowrap;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
vertical-align: middle;
line-height: normal;
height: auto;
margin-bottom: 4px;
padding: 0 20px 2px;
font-size: 1.02em;
text-align: center;
box-shadow: none;
.button.button-large {
font-size: 1.35em;
padding: 0px 35px 2px;
.button:focus {
background: #95A9CF;
border-color: #95A9CF;
box-shadow: 0px 0px 2px rgba(49, 78, 85, 0.5);
.button:active {
box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.1) inset;
<!-- Change the layout and structure the body however you want -->
<body id="error-page">
<?php endif; // ! did_action( 'admin_head' )
<div class="error-content">
<?php echo $message; ?>

This comment has been minimized.

Copy link

@nicStuff nicStuff commented May 28, 2015

Well done, but I find it incomplete as of today:

  • it seems that a "<html " just after <!DOCTYPE html> is missing;
  • I added it into my code and the output shown on page is "_default_wp_die_handler" regardless of the error message i use when calling wp_die;
  • it's odd that this filter isn't documented on it can be missing for many reasons, e.g. no one didn't add it to the wiki, or this is more a hack and then not reliable on a long term usage.

I would like to hear from you about this, so maybe I can use the code. Thank you


This comment has been minimized.

Copy link
Owner Author

@nat-c nat-c commented Jun 8, 2015

Hey nic! Sorry for not replying earlier.

You're absolutely right about the opening <html> tag! I missed it. --Which is weird, because most of the code is taken from the working one; the personal project I'm working on.

As for the Plugin_API/Filter_Refererence documentation (or actually the lack of it), I think it's because the WP Codex is always a work in progress. There are still a few "red links", i.e. actions and filters not documented, redirecting in an empty page...
Check out the wp_die() documentation instead: (The filters are listed in the notes at the bottom)
You can use the wp_die_handler filter to override the standard error pages since WP 3.0.

I'm not sure I'm following you in regards to the issues you're facing: You're not able to create and use a custom handler at all or you can't change the error message? :/

Here's a working example (from the CRM app I mentioned earlier): Imgur link
When someone not logged-in tries to access a specific page, wp_die() is called with the error message in the pic:
wp_die( __( "That&apos;s not the page you were looking for, right?" ) );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.