Jump to content

Nice error page with detailed error logging


HaLo2FrEeEk

Recommended Posts

I made a dynamic error page pre loaded with the 5 most common error codes: 400, 401, 403, 404, and 500.  This is a very neat script (as in tidy) and makes it so you only need one page for your error pages, instead of however many errors you want to specify.  It's simple to install too, I will outline the steps below:

 

Paste the code at the bottom into a file and call it error.php.

Change the includes to point to your site's header and footer files, or if you don't have them, simply remove the includes. I'm assuming your files are in the ROOT.

Upload that file to wherever you want it on your server, ROOT/errors/ should work, but whatever you want.

Add the following code into a file and name it .htaccess, append it to your current .htaccess file, or edit your current .htaccess file:

 

ErrorDocument 400 /errors/error.php?err=400
ErrorDocument 401 /errors/error.php?err=401
ErrorDocument 403 /errors/error.php?err=403
ErrorDocument 404 /errors/error.php?err=404
ErrorDocument 500 /errors/error.php?err=500

 

I'm assuming you put error.php into a folder called errors in the ROOT directory, change that if needed.

Upload your .htaccess file to your site's ROOT directory. This is important, the file must go there to affect your whole site, otherwise it will only affect the subfolders of the folder it is in.

Test it by going to a page that you know doesn't exist, if it shows the error message, it worked.  The error should look like this:

 

[error name]

 

[error description]

 

error occured on [date]

Web server [your server]

 

It will then write information about the error into log.txt located in the same directory as error.php, it writes errors to the log in this format:

 

-=BEGIN ERROR=-

Error [error code]: [error name]

Occured on: [date]

Client IP: [ip]

Client Compatible: [true/false]

Client Browser: [browser]

Client Version: [os version]

Client Operating System: [os]

Refering URL: [referer]

-=END ERROR=-

 

To view the log, navigate to the error.php page in your browser and add the variable err=log, so that the url looks like this:

 

http://yoursite.com/errors/error.php?err=log

 

Again, I'm assuming that you have put error.php in a folder called errors in the ROOT directory.

 

And that's it, it's installed and running.  Congratulations.  If you need any help, let me know and I will be more than happy to oblige.

 

Here is error.php:

 

<?php
$err = $_REQUEST['err'];
if(!$err) {
  die("No error code specified.");
  } else if(strtolower($err) == "log") {
  $title = "Error Log";
  include($_SERVER['DOCUMENT_ROOT'].'/header.php');
  echo elog();
  die(include($_SERVER['DOCUMENT_ROOT'].'/footer.php'));
  }

// Set $title to error name before calling header.php
$names = array("400"=>"Bad Request", "401"=>"Unauthorized", "403"=>"Forbidden", "404"=>"Page Not Found", "500"=>"Server Error");
if(!$names[$err]) { // This means that the error code specified isn't in your array
  die("Error code not recognized.");
  }
$title = $err." error: ".$names[$err];
include($_SERVER['DOCUMENT_ROOT'].'/header.php');

// Format log for viewing
function elog() {
  if(!file_exists('./log.txt')) {
    $file = "There is no log file to view.<br /><br />\n\n";
    return $file;
    }
  $file = implode('', file('./log.txt'));
  $file = str_replace("\n", "<br />\n", $file);
  return $file;
  }

// Get client info
$ua = $_SERVER['HTTP_USER_AGENT'];
$ua_s = strpos($ua, "(")+1;
$ua = substr($ua, $ua_s);
$ua_e = strpos($ua, ".NET")-2;
$ua = substr($ua, 0, $ua_e);
list($com, $brows, $ver, $os) = explode("; ", $ua);
$ip = $_SERVER['REMOTE_ADDR'];
$referer = $_SERVER['HTTP_REFERER'];
$time = date('l, F j, Y \a\t g:i a');
if(strtolower($com) == "compatible") {
  $com = "True";
  } else {
  $com = "False";
  }
if(!$referer) {
  $referer = "None";
  }

// Print error description
$descs = array("400"=>"I'm sorry, but it appears your browser has sent an unrecognizable request to the server, please try again.", "401"=>"This page is either password protected, or you are unauthorized to view it.", "403"=>"You do not have permission to access this document.", "404"=>"Sorry, the page you were looking for can not be located.", "500"=>"An unexpected error has occured on the server, if this is the first time this has happened, <br />please go <a href=\"javascript:history.back(1)\">back</a>, then try to access this page again.");
echo "<b>".$names[$err]."</b><br /><br />\n\n";
echo $descs[$err]."<br /><br />\n\n";
echo "<i>error occurred on ".$time."</i><br />\n";
echo "<i>Web Server <a href=\"http://".$_SERVER['SERVER_NAME']."\">".$_SERVER['SERVER_NAME']."</a></i><br /><br />";

// Prepare client info for addition into log.txt
$info = "-=BEGIN ERROR=-\n";
$info .= "Error ".$err.": ".$names[$err]."\n";
$info .= "Occured on: ".$time."\n";
$info .= "Client IP: ".$ip."\n";
$info .= "Client Compatible: ".$com."\n";
$info .= "Client Browser: ".$brows."\n";
$info .= "Client Version: ".$ver."\n";
$info .= "Client Operating System: ".$os."\n";
$info .= "Refering URL: ".$referer."\n";
$info .= "-=END ERROR=-\n\n";

// Add information to log.txt
$handle = fopen("./log.txt", 'a');
fwrite($handle, $info);
fclose($handle);

include($_SERVER['DOCUMENT_ROOT'].'/footer.php');
?>

 

Note: You can add more errors too, if you want, its quite simple.

Add the following to the end of the array $names:

 

, "[error number]"=>"[error name]"

 

Add this to the end of the array $descs

 

, "[error number]"=>"[error description]"

 

Then add this to your .htaccess file:

 

ErrorDocument [error number] /errors/error.php?err=[error number]

 

And that's it, the script will pick it up and use it if that error is encountered.

 

Another note: if log.txt doesn't exist, when an error is encountered it will be created, then appended in the future.  If it doesn't exist and you use error.php?err=log to view it, you will be notified that there is no log to view.  If err is not present, the script dies, notifying the user that there was no error code supplied.  If an error is requested that is not in your arrays (for example, if someone goes to error.php?err=501), the script will die notifying the person that that error code is not recognized.  I might update this so that it adds those two events to the log as well.

 

I hope this helps you guys, it only took me about 30 minutes, if even that, and I just thought it was so good I should post it here, the world needs things to be simplified like this, I'm just here to help.

Link to comment
Share on other sites

i couldn't read it all since it's big and i am in a hurry but do you think it is ok if you let people view your error log? in addition i think every server has capability (if it isn't default) of logging all errors what's the point of this file then?...

 

Even apart from the afore mentioned... the error document (the one that shows the error message) shouldn't be responsible for logging the error but the server should be for a simple reason... you cant be sure if there really was an error... Supposing i keep visiting error.php?err=500 every time i visit it there will be a log of an 'Internal Server Error' to your log file... Then you view the log and it has 200 errors so you think your server has a problem...

 

So in few words this is definitely not going to work and it shouldn't cause it poses a threat to your server or  in the best case (for your site) a misleading info provider to you...

 

Kathas

Link to comment
Share on other sites

Hardly, the purpose is to hide the error page in a place where it can't really be found by accident.  I made this becuase my server's error logging is in a different place, with the rest of the site monitoring, and I wanted something simple and effective.  If you don't want the error log, you can very easily remove it so it only shows the error message and not the error log, but it won't hurt.  It also wouldn't be that hard to change it so that if there is no referer (meaning if someone just visited the error page itself, if they did, there would be no refering url) then it wouldn't log the error, in fact, it would be really easy to do that.  Here, you could use this code:

 

<?php
$err = $_REQUEST['err'];
if(!$err) {
  die("No error code specified.");
  } else if(strtolower($err) == "log") {
  $title = "Error Log";
  include($_SERVER['DOCUMENT_ROOT'].'/header.php');
  echo elog();
  die(include($_SERVER['DOCUMENT_ROOT'].'/footer.php'));
  }

// Set $title to error name before calling header.php
$names = array("400"=>"Bad Request", "401"=>"Unauthorized", "403"=>"Forbidden", "404"=>"Page Not Found", "500"=>"Server Error");
if(!$names[$err]) { // This means that the error code specified isn't in your array
  die("Error code not recognized.");
  }
$title = $err." error: ".$names[$err];
include($_SERVER['DOCUMENT_ROOT'].'/header.php');

// Functions
function elog() {
  if(!file_exists('./log.txt')) {
    $file = "There is no log file to view.<br /><br />\n\n";
    return $file;
    }
  $file = implode('', file('./log.txt'));
  $file = str_replace("\n", "<br />\n", $file);
  return $file;
  }

function addlog($info) {
  $handle = fopen("./log.txt", 'a');
  fwrite($handle, $info);
  fclose($handle);
  }

function error($err) {
  GLOBAL $time, $names;
  $descs = array("400"=>"I'm sorry, but it appears your browser has sent an unrecognizable request to the server, please try again.", "401"=>"This page is either password protected, or you are unauthorized to view it.", "403"=>"You do not have permission to access this document.", "404"=>"Sorry, the page you were looking for can not be located.", "500"=>"An unexpected error has occured on the server, if this is the first time this has happened, <br />please go <a href=\"javascript:history.back(1)\">back</a>, then try to access this page again.");
  echo "<b>".$names[$err]."</b><br /><br />\n\n";
  echo $descs[$err]."<br /><br />\n\n";
  echo "<i>error occurred on ".$time."</i><br />\n";
  echo "<i>Web Server <a href=\"http://".$_SERVER['SERVER_NAME']."\">".$_SERVER['SERVER_NAME']."</a></i><br /><br />";
  }

// Get client info
$ua = $_SERVER['HTTP_USER_AGENT'];
$ua_s = strpos($ua, "(")+1;
$ua = substr($ua, $ua_s);
$ua_e = strpos($ua, ".NET")-2;
$ua = substr($ua, 0, $ua_e);
list($com, $brows, $ver, $os) = explode("; ", $ua);
$ip = $_SERVER['REMOTE_ADDR'];
$referer = $_SERVER['HTTP_REFERER'];
$time = date('l, F j, Y \a\t g:i a');
if(strtolower($com) == "compatible") {
  $com = "True";
  } else {
  $com = "False";
  }
if(!$referer) {
  error($err);
  die(include($_SERVER['DOCUMENT_ROOT'].'/footer.php'));
  }

// Print error description
error($err);

// Prepare client info for addition into log.txt
$info = "-=BEGIN ERROR=-\n";
$info .= "Error ".$err.": ".$names[$err]."\n";
$info .= "Occured on: ".$time."\n";
$info .= "Client IP: ".$ip."\n";
$info .= "Client Compatible: ".$com."\n";
$info .= "Client Browser: ".$brows."\n";
$info .= "Client Version: ".$ver."\n";
$info .= "Client Operating System: ".$os."\n";
$info .= "Refering URL: ".$referer."\n";
$info .= "-=END ERROR=-\n\n";

// Add information to log.txt
addlog($info);

include($_SERVER['DOCUMENT_ROOT'].'/footer.php');
?>

 

But this would only register it if the person clicked on a link that was dead, it would help you to find lead links to places on your site, but not with much else.  Like I said, you can remove the logging alltogether if you want, I just thought it wasn't that difficult to add so why not.

Link to comment
Share on other sites

Sorry for the late reply (have been out of town)...

 

Checking the referrer is still not security wise cause it is very easy to pretend to be referred from some page while you do the request. But since logging the error is not the case who cares if the user sees an error msg he requested to see right?

 

Now as far as you dont use this page for logging your server's errors i can see no harm done and it propably is a nice way to show your error messages...

 

Kathas

Link to comment
Share on other sites

Well...thanks I guess.  Like I said the error logging was a last minute addidtion...I see what you mean, I've let it run unhindered since I last posted and the text file is already 80 Kb's, which is considerable seeing as each character is one byte, so there are 80,000+ characters in the log.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.