1

I've written the following custom Exception handler:

namespace System\Exception;

class Handler extends \Exception {


    public static function getException($e = null) {

        if (ENVIRONMENT === 0 && is_object($e)) {       
            $message  = "<p>";
            $message .= "Exception: " . $e->getMessage();
            $message .= "<br />File: " . $e->getFile();
            $message .= "<br />Line: " . $e->getLine();
            $message .= "<br />Trace: " . $e->getTrace();
            $message .= "<br />Trace as string: " . $e->getTraceAsString();
            $message .= "</p>";
        } else {
            $message  = '<h1>Exception</h1>';
            $message .= '<p>There was a problem.</p>';
        }

        @require_once('header.php');
        echo $message;
        @require_once('footer.php');

        exit();

    }


    public static function getError($errno = 0, $errstr = null, $errfile = null, $errline = 0) {
        if (ENVIRONMENT === 0) {        
            $message  = "<p>";
            $message .= "Error: " . $errstr;
            $message .= "<br />File: " . $errfile;
            $message .= "<br />Line: " . $errline;
            $message .= "<br />Number: " . $errno;
            $message .= "</p>";
        } else {
            $message  = '<h1>Error</h1>';
            $message .= '<p>There was a problem.</p>';
        }

        @require_once('header.php');
        echo $message;
        @require_once('footer.php');

        exit();

    }   


    public static function getShutdown() {
        $last_error = error_get_last();
        if ($last_error['type'] === E_ERROR) {
            self::getError(E_ERROR, $last_error['message'], $last_error['file'], $last_error['line']);
        }
    }


}

and have indicated that I want to use this class and its methods for processing all exceptions and errors generated by the system in the following way:

set_exception_handler(array("System\Exception\Handler", "getException"));
set_error_handler(array("System\Exception\Handler", "getError"), -1 & ~E_NOTICE & ~E_USER_NOTICE);
register_shutdown_function(array("System\Exception\Handler", "getShutdown"));

I have also indicated that I don't want errors to be displayed on the screen and wand to report all of the errors:

ini_set('display_errors', 'Off');
error_reporting(-1);

My question now is - do I still need to use the try { } catch () { } statement in order to catch any exceptions and errors? I know that the above is most probably not a bullet proof, but seem to be working so far without any try / catch statement by processing all uncaught exceptions and errors.

Also - is there any disadvantage by using custom exception handler and letting it catch all uncaught exceptions rather than doing this via try {} catch (i.e. performance / security etc.)?

Spencer Mark
  • 5,263
  • 9
  • 29
  • 58
  • The global exception handler in PHP catches all exceptions that have not been caught by a try catch statement yet. – knittl Aug 03 '12 at 16:47

2 Answers2

3

You don't have to, but you cannot recover - using try/catch gives you the advantage of reacting to particular exception (for example file not found in some_custom_session_handling() might be a good place to use try/catch and log out such user without session file).

So the advantage is that you have prettier messages. The downside is that you treat exceptions always the same. It's not bad in itself, and should not degradate performance or security, but it misses the point of using exceptions in the first place.

However, it does not exclude using try/catch where you might want them, so I'd say it's a good failover solution, but should be avoided as a try/catch replacement

jderda
  • 890
  • 6
  • 18
  • Thanks jderda. My code catches all possible errors as well - so if there is a chance that the error might occur it will also be processed and the relevant error message displayed in a nicely formatted way. Some of the errors cannot be processed, but at least they won't be shown at all. With the custom Exception handler as the one I've written, wrapping any code within try / catch doesn't seem to affect anything as it's still processed by this custom handler. – Spencer Mark Aug 03 '12 at 16:55
  • Sure, but to give you real-life example where it might be good idea to rely on try/catch imagine a business-important application, which uses SOAP requests to send some stats. If sending stats (let's say unimportant ones) fails, you probably still want to execute the rest of the code. That's where your code loses on try/catch. But in most cases as you said, it's just easier and simpler :) – jderda Aug 03 '12 at 16:59
  • I see what you mean. The same will fail with any ajax calls which throw exception as they won't be able to return the custom response. I might gonna have to re-think it :) – Spencer Mark Aug 03 '12 at 17:02
  • Actually - I've just tried and I can still use the try / catch with this approach to get response - so it's actually working both ways - if uncaught - will be processed by the custom handler - if caught - then it will be processed accordingly. – Spencer Mark Aug 03 '12 at 17:05
0

As jderda said, be using your aproach you are missing the point of exceptions: to check for any errors in the upper levels of your code and react to them - halt or treat the exception and move on. Your aproach is fine when you want to, for example, log all uncaught exceptions

Vlad Balmos
  • 3,372
  • 19
  • 34
  • 1
    This is a good comment, but it should be a comment on jerda's answer, not a new one. Cheers! :-) – Matt Aug 03 '12 at 19:19