Categories
PHP

PHP Error handling

When there are problems, always return an Exception object to the client.

Exception constructor accepts two optional arguments: an error string (error description in “plain english”) and an error code.

These are the Exception object’s public methods available:

  • getMessage() – Get the message string that was passed to the constructor.
  • getCode() – Get the code integer that was passed to the constructor.
  • getFile() – Get the file in which the exception was generated.
  • getLine() – Get the line number at which the exception was generated.
  • getTrace() – Get a multidimensional array tracing the method calls that led to the exception, including method, class, file, and argument data.
  • getTraceAsString() – Get a string version of the data returned by getTrace().
  • __toString() – Called automatically when the Exception object is used in string context. Returns a string describing the exception details.

The “throw” keyword basically stops the current method’s execution, passing an Exception object back to the calling client, and expecting it to handle the exception problem raised.

Error handling best practices call for subclassing Exceptions, so you have an exception per type of error, and handle the problem according to the exception type:

class XmlException extends Exception {
    private $error;

    function __construct( LibXmlError $error ) { // In this case we are expecting a LibXmlError already, but not
           // neecesary to have Type Hinting here
        $shortfile = basename( $error->file );
        $msg = “[{$shortfile}, line {$error->line}, col {$error->col}] {$error->message}”;
 $this->error = $error;
      parent::__construct( $msg, $error->code ); // Exception parent class is still called
    }

  function getLibXmlError() {
      return $this->error;
  }
}

class FileException extends Exception { } // Classes not “filled out yet”, but they will handle
class ConfException extends Exception { } // other kind of exceptions simmilar to XmlException

A typical client code that takes care of multiple exception types will look like this:

class Runner {
     static function init() {
        try {
            $conf = new Conf( dirname(__FILE__).”/conf01.xml” );
            print “user: “.$conf->get(‘user’).”n”;
            print “host: “.$conf->get(‘host’).”n”;
            $conf->set(“pass”, “newpass”);
            $conf->write();
        } catch ( FileException $e ) {
           // permissions issue or non-existent file
        } catch ( XmlException $e ) {
           // broken xml
        } catch ( ConfException $e ) {
           // wrong kind of XML file
        } catch ( Exception $e ) {
           // backstop: should not be called
        }
    }
}

When you have multiple catches this way, the first catch that matches the Exception type will be executed, so always try to put the more generic errors at the end. At this point, when an exception is catched, you can throw it again for further handling in subsequent catches.

Leave a Reply

Your email address will not be published. Required fields are marked *