Jan 13

Para conseguir que los errores de PHP lancen exceptions en lugar del clásico mensaje por pantalla y/o entrada en el log, dependiendo de las directivas de configuración usadas, es necesario redefinir el handler de errores del intérprete. Esto es muy útil si estamos programando con PHP5 una aplicación orientada a objetos usando excepciones personalizadas para tratar los errores de nuestro código. En esta situación sólo nos falta capturar los errores del PHP y convertirlos en excepciones para conseguir tratar de la misma forma cualquier error que se produzca ya sea de nuestro código o del intérprete.

El código necesario es el siguiente:

[php] class MyException extends Exception {
public $file;
public $line;
public function errorHandler($errno, $errstr, $errfile, $errline) {
$e = new self();
$e->message = $errstr;
$e->code = $errno;
$e->file = $errfile;
$e->line = $errline;
throw $e;
}
}
set_error_handler(array(‘MyException’, ‘errorHandler’), E_ALL); [/php]

Si ya dispones de una clase exception personalizada puedes simplemente añadirle el método errorHandler y lanzar una de tus excepciones ante un error del PHP. Es necesario colocar este código antes de que haya empezado la ejecución de tu aplicación, una buena técnica es crear un script y hacer que la directiva auto_prepend_file apunte a su ubicación… en general yo encuentro cómodo redefinir todos los handlers necesarios en el auto_prepend_file (por ejemplo nuestros handlers de sesiones, errores y excepciones).

Tener en cuenta que en el anterior código PHP fijo el nivel de errores a E_ALL, esto provoca que se lancen exceptions con los E_NOTICE. Si para ti es demasiado que se lance una excepción porque no has inicializado una variable puedes sustituir la línea con la llamada a set_error_handler por:

[php] set_error_handler(array(‘MyException’, ‘errorHandler’), E_ALL ^ E_NOTICE); [/php]

Puedes consultar más información acerca de los niveles de error del PHP en la documentación de la función error_reporting, también puedes pegarle un vistazo al post Controlar el Script PHP: set_time_limit, memory_limit y error_reporting publicado en SyntaxError.es, un blog amigo dentro de la red SmallSquid.com. Es interesante también consultar la documentación de set_error_handler para más información acerca de los handlers de errores.

Podéis comprobar que el handler funciona con el siguiente código de test:

[php] try {
$a + 2;
print ‘aquí no llegamos ya que $a no está inicializada’;
} catch (Exception $e) {
print ‘Excepción capturada! ‘.”\n”;
print ‘Code: ‘.$e->getCode().”\n”;
print ‘Message: ‘.$e->getMessage().”\n”;
print ‘Line: ‘.$e->getLine().”\n”;
print ‘File: ‘.$e->getFile().”\n”;
} [/php]

A pesar de redefinir el handler de errores los fatal errors nunca podrán ser capturados mediante nuestro error handler ya que el intérprete se queda en un estado inestable y necesita de una terminación rápida y limpia. En un siguiente post explicaré como tratar estos casos.

Tagged with:
preload preload preload