Blog Post RSS ?

Blogs » PHP » User Errors in PHP
 

User Errors in PHP


  • Save to
    Del.icio.us

by Thomas Rutter

The trigger_error function in PHP allows you to generate a PHP error on demand. If you haven’t used this function before, you may be asking, “Why would you want to generate an error?” Well, it is a much more flexible solution than using exit or die to display your error message.

Often, while editing legacy PHP code, I come across error handling for situations such as database connect errors:

$dbconn = mysql_pconnect($myhost, $myuser, $mypass); if (!$dbconn) exit(mysql_error());

Or, the lazier version:

$dbconn = mysql_pconnect($myhost, $myuser, $mypass) or die('yikes');

The problem with this approach, which uses exit (or its alias, die), is that it doesn’t give PHP a chance to use its own error handling method. It will always terminate the script and print its little error message to the screen.

So, for example, you won’t be able to turn the error messages on or off with the php.ini directive display_errors, you won’t be able to log the error to your error log with log_errors, and you won’t be able to use your own custom error handler function.

Why is this a bad idea? Well, on a live server it is sometimes a security risk (and an embarrassment) if your error messages are displayed to the public. From the PHP manual:

Note: You’re strongly advised to use error logging in place of error displaying on production web sites.

However, when you use trigger_error, the error will be processed according to PHP’s error handling routines.

$dbconn = mysql_pconnect($myhost, $myuser, $mypass); if (!$dbconn) trigger_error('Database connection failure', E_USER_ERROR);

Here, I used E_USER_ERROR to indicate a fatal run-time error. Other error level constants can be used to trigger warnings or notices.

On a test server, you can turn display_errors on and the error, complete with line number and source file, will be displayed on screen. On a live server, you can turn it off, and instead enable log_errors and the error message, complete with line number and source file, will be output to your error log.

This post has 13 responses so far

  1. Thanks for the info. Never realized it could be used like that, and wondered why some applications used a method similar to that.

     
  2. I generally only use this for programming errors, in conjunction with the xdebug, extension (which does backtraces for you), it is a very usefull tool.

    It however gets very messy for managing program flow errors, having to use @ and the $error_msg variable dont make for very readable code. Exceptions (PHP5) or PEAR::Error (PHP4) are better suited to that.

     
  3. When using PHP 5 you should definately use exceptions instead of killing your application (die, trigger_error, …).

    Basically every error should be thrown, no matter whether it’s fatal or not. This way it’s the code’s client’s decision if and where to catch it, wheter it’s fatal and what to do with it.

    Who knows, maybe your mysql connection error could be recovered from by using an alternate server. Too bad the application would already be stone-dead after the first attempt. :)

    Then again you could use E_USER_WARNING or E_USER_NOTICE but without a custom error handler your client code would miss those errors.

    In my opinion trigger_error only goes well with very simple functional applications.

     
  4. I’ve never really looked into trigger_error; I guess now I will. Thanks for the article.

     
  5. Check also function set_error_handler(). You can define your own function (or class) to handle errors. For example i use it for storing errors and also for email notification if FATAL error ocure. It also backtrace all function calls.

     
  6. wheee! another function added to my growing “mental” repository of PHP functions. Since I’m making that jump from intermediate to advanced transition and learning the techniques to do so this is defeinitely going to be used for better error handling.
    Nice post Thomas!

     
  7. When using PHP 5 you should definately use exceptions instead of killing your application

    For every exception that is thrown, it either has to be caught, or generate an uncaught exception error.

    If it is caught, you still have the problem of deciding what to do when the error is caught. Wouldn’t you agree?

    Obviously, if you can recover from the situation you wouldn’t have to exit or use trigger_error. However, if it’s unrecoverable, what do you do when you catch the exception? Do you display an error message to the screen or do you log the error? Exception handling doesn’t define what to do when an exception is caught, it just provides a way of catching an exception. If you are on a live server, you don’t want to display a diagnostic error message, which will reveal a lot about your application, to the public. You want it to be quietly logged. However, if you are on a testing server, then having diagnostic information shown on screen is desirable.

    Consider the following code:

    try { $error = 'Always throw this error'; throw new Exception($error); // Code following an exception is not executed. echo 'Never executed'; } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; }

    When the exception is caught, all that is done is an error message is displayed on screen. If we replaced ‘echo’ with ‘trigger_error’, then we could use PHP’s error handling to decide what to do with the error. It’s easy to define custom error handling with ’set_error_handler’.

     
  8. When the exception is caught, all that is done is an error message is displayed on screen

    In your trivial example yes

    The power of exceptions is, as Maarten Manders said, to be able to recover from the exceptional behaviour that has occurred. To use his example, you can catch whatever exception is thrown when a connection can’t be established to the MySQL server. To recover from the exception you could use a cached version of the data, connect to another server or something else. However, if you know your application can’t recover after a failed attempt to connect to the MySQL server then you can leave the exception to be caught with a custom exception handler (see set_exception_handler()) and log it, email it, show a general message or a debug page or anything else

    Sean :)

     
  9. I’d love to see how “martinpav”, or anyone else fo rthat matter, writes & implements custom error handling that emails you when certain erros occur. Goo idea for an article?

     
  10. One tip. If you throw an error in a method, don’t forget to return straight afterwoods. trigger_error() won’t terminate your code if someone has installed a custom error handler and will run on and cause additional damage.

    yours, Marcus

     
  11. trigger_error() won’t terminate your code if someone has installed a custom error handler and will run on and cause additional damage.

    I believe it is the duty of a custom error handler to terminate the program if the error level is fatal (E_ERROR or E_USER_ERROR).

     
  12. Good stuff..

    I’ve used something like..

    @mysql_connect() or mysqlMessedUp(mysql_error());

    to email me or whatever with the error, and then exit out in the custom function…

    PHP5’s throwing and catching thing looks quite nice, like Java.. ;)

     
  13. Before debug_backtrace was introduced, I used to use trigger_error to trace errors. What I did was to set up a custom errorhandler, witch pushed errors to a stack if they were of E_WARNING, and then doing something like this :

    function first() { second(); if (is_error()) { trigger_error("something failed", E_USER_WARNING); } } function second() { trigger_error("something failed", E_USER_WARNING); } first(); if (is_error()) { trigger_error("something failed", E_USER_ERROR); }

    is_error checks if the stack contains any errors.
    This allowed my to dump a stacktrace, witch is very useful when debugging your application.

     

Sponsored Links

Leave a response

You are not logged in, log in with your SitePoint Forum username and password.

-OR- Post Anonymously

* Make sure any code samples are escaped (i.e. ‘<b>’ becomes ‘&lt;b&gt;’).

If not logged in, your comments will be placed in a moderation queue. This means your comment may not appear until one of our moderators approves it.

SitePoint Marketplace

Buy and sell Websites, templates, domain names, hosting, graphics and more.

Logo Design, Web page Design and more!

99designs

  • Custom logo designs created ‘just for you’.
  • Pick the design you like best.
  • Only pay if you’re satisfied with the result.

It's Back!
FREE PDF with any printed book!