2010-11-28 12 views
5

Soy relativamente novato en PHP, pero me parece que el manejo de errores de PHP es un poco un ghetto, con errores y advertencias intercalados con excepciones (y no me enciende en die()). Como tal, no estoy seguro de cuál es la mejor manera de crear, interpretar y manejar todos los casos de error en mi aplicación.¿Hay algún "inconveniente" con este enfoque para manejar errores en PHP?

Mi plan general de ataque es más o menos de la siguiente manera:

  1. convertir todas las advertencias/errores en Excepciones, utilizando set_error_handler() para envolver los errores como vienen.
  2. Código de forma preventiva, comprobando de forma preventiva las cosas que espero que salgan mal. Lanzar excepciones solo cuando no puedo manejar el error directamente. Los bloques habituales de try/catch estarán en su lugar cuando sea necesario, para manejar excepciones que no me arrojo.
  3. Envuelva toda mi aplicación (es decir, mi archivo de punto de entrada index.php) en su propia try/catch. Si eso falla, lanzaré un HTTP 500 y mostraré una página de error adecuada. Presumiblemente, esta página será un único archivo precompilado en lugar de una colección de encabezado/cuerpo/pie de página incluye, esto es en gran medida para que yo todavía pueda cubrir excepciones raras como un archivo de plantilla ilegible. Supongo que esta es la razón por la cual la página de error de 500 clases de Google se ve muy diferente de todo lo demás que publicaron.
  4. Como corolario de los n. ° 2 y n. ° 3, dado que espero manejar todo por adelantado, si decido lanzar mi propia excepción, también espero no para detectar el error y, en su lugar, dejarlo burbujear todo el camino hasta mi controlador de nivel superior. El pensamiento aquí es que si no puedo manejarlo cuando sucede, probablemente esté mal equipado para manejarlo en cualquier otro lado. Estoy pensando en darles a estos errores su propia subclase, quizás CriticalErrorException, que se pueda identificar directamente en mis registros/generar un correo electrónico para que pueda verlo rápidamente. En general, espero que estos sean los elementos que pueden suceden en dev, pero deben ser resueltos por producción.
  5. Cualquier error que llegue a la parte superior se registra en la base de datos, con conmutación por error a un archivo de registro. Los errores críticos, como se indicó anteriormente, desencadenan un correo electrónico. Si el informe falla en el archivo, es decir, hay un error en la base de datos, también se activará un correo electrónico.

Creo que esto cubre la mayoría de los casos bastante bien, pero como he dicho, soy muy nuevo en PHP, así que no sé si hay casos de esquina o comportamientos extraños que estoy pasando por alto.

¿Cuáles son los defectos en mi plan? ¿Cómo puedo superarlos?

+0

Ese es un enfoque sólido, sí. – DanMan

Respuesta

1

En general, la estrategia de permitir que las excepciones inesperadas se conviertan en un bloque catch superior y luego servir un HTTP 500 está bien (muchos frameworks hacen precisamente eso).

No estoy del todo de acuerdo con hacer un CriticalErrorException - tal vez no espere ver algo ahora, pero puede ampliar su manejo de errores en el futuro (posiblemente en vista de requisitos adicionales de la aplicación). Solo tira lo que sea natural. Un simple Exception está bien en la mayoría de los casos.

En cuanto a los errores de PHP: no es necesario convertir estrictamente E_ERROR en una excepción (de todos modos, matará su aplicación y aparecerá en el registro de errores también). Haría bien en manejar E_NOTICE, ya que los avisos casi siempre significan que hay algo mal con el código.

Por último, cuando se habla de funciones PHP que elevan advertencias, me gustaría ir con esto:

// Assume that php_function() raises E_WARNING and returns FALSE on error 
// WARNING: if you have defined a custom error handler, IT WILL STILL BE CALLED 
//   even though the @ operator suppresses the error 
$result = @php_function($argument); // suppress error 
if (!$result) { 
    // error handling here 
} 

en lugar de esto:

try { 
    $result = php_function($argument); 
} 
catch (Exception $ex) { 
    // error handling here 
} 

La razón es que la conversión a una excepción no lo hace realmente te compro algo cuando pretendes reaccionar al error de inmediato. Por el contrario, el primer fragmento de código "indicará" a un desarrollador que lo lea que busque la documentación para php_function si se necesita más información sobre su estrategia de manejo de errores. El segundo fragmento de código requerirá que el desarrollador tenga conocimiento sobre el manejo de errores específicamente según se implementa en su aplicación.

Actualización:

No estoy diciendo que usted debe utilizar @ simplemente ignorar los errores que salen de las llamadas a funciones. Lo que estoy diciendo es que, al usar funciones PHP heredadas que se comportan de esta manera, y cuando está completamente preparado para manejar el error y recuperarse de él, entonces, por supuesto, ya no debe considerarse un "error" con respecto a la ejecución de su aplicación. En este caso específico, recomiendo suprimirlo para que no se informe también.

+0

tu @php_function ($ argumento); es simplemente terrible. @ no tiene nada que hacer aquí. Y está estropeando el manejo de errores con informes de errores aquí. Si bien es diferente. Se debe informar un error siempre, * independientemente * del manejo. –

+0

Cualquier argumento que no sea "No me gusta"? – Jon

+0

Entonces, a) No puedo atrapar E_ERROR sin importar nada; simplemente va a matar mi aplicación donde está y no será manejable (¿estas cosas son como errores de sintaxis que deberían detectarse antes de la producción, o a veces aparecen inesperadamente?), yb) ¿No debería incluir todo en una excepción en una función de manejador de error personalizado en caso de que quiera usar la supresión '@'? ¿Cuál es una "buena" forma de escribir el controlador de error personalizado en general? – AgentConundrum

Cuestiones relacionadas