Pregunta

Esto está escrito en PHP, pero en realidad es independiente del idioma.

try
{
    try
    {
        $issue = new DM_Issue($core->db->escape_string($_GET['issue']));
    }
    catch(DM_Exception $e)
    {
        throw new Error_Page($tpl, ERR_NOT_FOUND, $e->getMessage());
    }
}
catch(Error_Page $e)
{
    die($e);
}

¿Los bloques try y catch anidados son una buena práctica a seguir?Parece un poco voluminoso solo para una página de error; sin embargo, mi administrador de datos de problemas arroja una excepción si ocurre un error y considero que es una buena forma de detectar errores.

La excepción Error_Page es simplemente un compilador de páginas de error.

Puede que sea pedante, pero ¿crees que esta es una buena manera de informar errores? Si es así, ¿puedes sugerir una mejor manera de escribir esto?

Gracias

¿Fue útil?

Solución

Estás utilizando excepciones para la lógica de la página y, personalmente, creo que eso no es bueno.Las excepciones deben usarse para señalar cuando suceden cosas malas o inesperadas, no para controlar la salida de una página de error.Si desea generar una página de error basada en excepciones, considere usar set_exception_handler.Cualquier excepción no detectada se ejecuta mediante cualquier método de devolución de llamada que especifique.Tenga en cuenta que esto no detiene la "mortalidad" de una excepción.Después de pasar una excepción a través de su devolución de llamada, la ejecución se detendrá normalmente después de cualquier excepción no detectada.

Otros consejos

Creo que sería mejor que no anidaras.Si espera múltiples tipos de excepciones, tenga múltiples capturas.

try{
  Something();
}
catch( SpecificException se )
{blah();}
catch( AnotherException ae )
{blah();}

Lo ideal es que las excepciones se detecten en el nivel que pueda manejarlas.Ni antes (pérdida de tiempo), ni después (pierdes contexto).

Entonces, si $tpl y ERR_NOT_FOUND son información que sólo se "conoce" cerca de la nueva llamada DM_Issue, por ejemplo porque hay otros lugares donde crea un DM_Issue y desearía ERR_SOMETHING_ELSE, o porque el valor de $tpl varía, entonces Estamos detectando la primera excepción en el lugar correcto.

Cómo llegar desde ese lugar a la muerte es otra cuestión.Una alternativa sería morir allí mismo.Pero si hace eso, entonces no habrá oportunidad de que el código intervenga haga nada (como aclarar algo de alguna manera o modificar la página de error) después del error pero antes de salir.También es bueno tener un flujo de control explícito.Entonces creo que eres bueno.

Supongo que su ejemplo no es una aplicación completa; si lo es, probablemente sea innecesariamente detallado y podría simplemente morir en la cláusula de captura DM_Exception.Pero para una aplicación real, apruebo el principio de no morir simplemente en medio de la nada.

Dependiendo de sus necesidades, esto podría estar bien, pero generalmente dudo bastante en detectar una excepción, envolver el mensaje en una nueva excepción y volver a enviarlo porque pierde la información de seguimiento de la pila (y potencialmente otra) de la excepción original en el envoltorio. excepción.Si eres seguro que no necesita esa información al examinar la excepción de ajuste, entonces probablemente esté bien.

No estoy seguro acerca de PHP pero, por ej.C# puede tener más de un bloque catch, por lo que no hay necesidad de combinaciones try/catch anidadas.

En general, creo que el manejo de errores con try/catch/finally siempre es de sentido común, también para mostrar "sólo" una página de error.Es una forma limpia de manejar errores y evitar comportamientos extraños al fallar.

No lanzaría una excepción por un problema no encontrado: es un estado válido de una aplicación y no necesita un seguimiento de la pila solo para mostrar un 404.

Lo que hay que detectar son fallos inesperados, como errores de SQL; ahí es cuando el manejo de excepciones resulta útil.Cambiaría tu código para que se parezca más a esto:

try {
    $issue = DM_Issue::fetch($core->db->escape_string($_GET['issue']));
}
catch (SQLException $e) {
    log_error('SQL Error: DM_Issue::fetch()', $e->get_message());
}
catch (Exception $e) {
    log_error('Exception: DM_Issue::fetch()', $e->get_message());
}

if(!$issue) {
    display_error_page($tpl, ERR_NOT_FOUND);
}
else
{
    // ... do stuff with $issue object.
}

Las excepciones deben usarse solo si hay un evento que potencialmente interrumpa el sitio, como una consulta de base de datos que no se ejecuta correctamente o algo está mal configurado.Un buen ejemplo es que el proceso de Apache no puede escribir en un directorio de caché o de registro.

La idea aquí es que las excepciones son para que usted, el desarrollador, detenga el código que puede dañar todo el sitio para poder solucionarlo antes de la implementación.También son controles de cordura para garantizar que si el entorno cambia (es decir,alguien altera los permisos de la carpeta de caché o cambia el esquema de la base de datos) el sitio se detiene antes de que pueda dañar algo.

Entonces no;Los controladores de captura anidados no son una buena idea.En mis páginas, mi archivo index.php envuelve su código en un bloque try...cache - y si sucede algo malo, verifica si está en producción o no;y me envía un correo electrónico y muestra una página de error genérica, o muestra el error directamente en la pantalla.

Recordar:PHP no es C#.C# es (con la excepción (jeje, sin juego de palabras :p) de ASP.net) para aplicaciones que contienen estado, mientras que PHP es un lenguaje de programación sin estado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top