开发者

Error handling with exceptions in console application - Exceptions not being caught

I am building up a relatively small but mission critical app that will synchronise two databases. This app will be running as scheduled task once a night when deployed, most probably unsupervised.

The problem I have is a lot of error开发者_开发技巧s are not displayed by the exception handling mecanism I (tried) to implement. Errors aren't thrown or caught, I don't know wich and debugging is very laborius as a lot of errors (most) are not displayed to console as expected.

Basically what I am striving for is to have it send errors to console when coding, and to logs and email when in production mode. I have setup a constant defined at beginning of script:

define("APPMODE", "DEBUG");

I have setup a custom error handler as such:

/*
 * Gestionnaire d'erreur qui trappe les erreures et warnings.
 * et les renvois sous formes d'exceptions.
 */
function CustomErrorHandler($errno, $errstr, $errfile, $errline) {
  if ( $errno >= 2 ) {
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
    // return true;
  }
  return false;
}

This error handler and other error settings are initialised in a static class function like so:

 /**
  *   Configuration de la gestion d'erreurs
  */
  static function initErrorHandling($config){   

 /* 
  *   Lance des exceptions avec toutes les erreures 
  *   Permet de rediriger vers fichiers logs ou courriels.
  */
  set_error_handler('CustomErrorHandler');

  // Adapts error handling according to APPMODE
  error_reporting($config->error_level); 

  ini_set('display_startup_errors', $config->display_errors);

  }

Now, armed with this, I though all I need to do is define proper exception handling mecanisms ie implement the logic to log and send emails when necessary in an extended exception class. Here is me main exception class:

<?php
class InitException extends Exception{
  protected $previous;
  // Redefine the exception so message isn't optional
    public function __construct($message, $code = 0, Exception $previous = null) {

     $this->previous = $previous;
        // make sure everything is assigned properly
        parent::__construct($message, $code, $previous);
    }
    // Send message to logfile or console depending on APPMODE
    public function __toString() {
      $logfile = 'C:\tirelinkCRMsynch\logs\customerAccountsSync.log';
        switch(APPMODE){
        /*
         *  This mode writes errors to logfile and sends a notice by email.
         */
          case 'PROD': 
            $message = "\r\n"  . date(DATE_ATOM) . " ". __CLASS__ . ": [{$this->code}]: {$this->getMessage()} \r\n\t\t\t\t\t\t  in {$this->getFile()} , line {$this->getLine()}\r\n";
        $message .= "Previous = {$this->previous}";
        // Mail the error
        mail_error($message);
        // Log error
        if (is_writable($logfile)){ 
          if (!$handle = fopen($logfile, 'a')) {
            echo "Cannot open file ($logfile)";
            exit;
          }
          // Write $message to our opened file.
           if (fwrite($handle, $message) === FALSE) {
            echo "Cannot write to file ($logfile)";
            exit;
          }
          fclose($handle);
        }else{
           echo "Cannot write to ($logfile)";
           exit;
        }
          return "Caught Exception of type [" . __CLASS__ . "] -> check logfile for more info.\r\n";
        break;
      /*
       *  DEBUG mode writes errors to console
      */
      case 'DEBUG': //
        return  "Caught exception of type " . __CLASS__ . ": [{$this->code}]: {$this->message} in {$this->getFile()} on line {$this->getLine()}.\r\nPrevious = {$this->previous}";
      break;
    } 
}

public function mailError($msg) {
 // to do - setup zend_mailer      
       $mail = '';
       echo "Mailed";
}

Now. Last but not least, the "catch blocks". I am truly not certain I am doing things the proper way in this section. My idea was that since the script represents one unit of work when it is executed, the whole script is wrapped in a try-catch block, catch blocks placed after the final exit of the script:

   <code for processing above>
  exit();

} catch (Zend_Config_Exception $e){

    throw new InitException($e->getMessage(), 100, $e); 

}   catch (Zend_Mail_Transport_Exception $e){

    throw new InitException($e->getMessage(), 200, $e);

}  catch (Zend_Mail_Exception $e){

    throw new InitException($e->getMessage(), 300, $e);

} catch (Zend_Exception $e){

    throw new InitException($e->getMessage(), 400, $e);

} catch (ErrorException $e){

    throw new InitException($e->getMessage(), 500, $e);

} catch (DBException $e){

    throw new InitException($e->getMessage(), 600, $e);

}  catch (InitException $e){ // Cette clause attrape toutes les erreures / warnings du script.

     $e->__ToString();

} catch (Exception $e){
     echo  $e->__toString();
     die ("Caught generic exception in {$e->getFile()} on line  {$e->getLine()}");
}
?>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜