I'm writing a PHP web application which will be running under a production environment in the not too distant future, and rather than use the non-user-friendly die()
, I thought I'd come up with a Class
that handles ErrorMessages.
Basically, my thought process is this:
If the web application is in debug/development mode, die() is OK.
If the web application is in production/live mode, don't disturb the user with the error message - instead continue as best as possible but send an e-mail to the admin, dumping the error message and anything else we can (e.g: logged in user, session details, IP address, time, etc.)
My (rough) code is as follows:
<?php
require_once('config.php');
class ErrorMessage
{
private $myErrorDescription;
public function __construct($myErrorDescription)
{
$this->myErrorDescription = (string) $myErrorDescription;
if (DEBUG_MODE === true)
die($myErrorDescription);
else
$this->sendEmailToAdministrator();
}
private function sendEmailToAdministrator()
{
// Send an e-mail to ERROR_LOGGING_EMAIL_ADDRESS with the description of the problem.
}
}
?>
This Class
would be used as:
if (EXPECTED_OUTCOME) {
// ...
}
else {
new ErrorMessage('Application failed to do XYZ');
}
Is this a sensible approach or am I reinventing the wheel here? I know that frameworks often have solutions for Error Handling, but I'm not using one (and don't really want to).
That said, should I be using Exceptions
and Throw
for this instead? What are the pros/cons of this approach?
I would suggest using Exceptions.
You can switch php over to sending Exceptions instead of errors by doing this: (from PHP ErrorException Page)
<?php
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
set_error_handler("exception_error_handler");
/* Trigger exception */
strpos();
?>
Then in your code when you encounter an error condition throw an Exception
throw(new Exception("Meaningful Description", "optional error number"));
Exceptions can be typed so you can derive an instance so that you can target it in a catch
class MyRecoverableException extends Exception {}
Then in your code you can enclose code that may throw a potentially recoverable error in a try/catch block.
try {
$res = doSomething();
if (!$res) throw new MyRecoverableException("Do Somthing Failed");
} catch(MyRecoverableException $e){
logError($e);
showErrorMessage($e->getMessage());
}
This is especially useful in Database Transactions
try {
$db->beginTransaction();
// do a lot of selectes and inserts and stuff
$db->commit();
} catch (DBException $e){
$db->rollback();
logError($e);
showErrorMessage("I was unable to do the stuff you asked me too");
}
with error reporting turned on, an uncaught exception will give you a detailed stack trace that tells you where the exception was thrown.
with error reporting turned off you will get a 500 Error.