¿Se considera una mala práctica el uso de Excepciones en el nivel más alto de un programa? [duplicar]

12

He visto programas que utilizan esta estrategia y también he visto publicaciones que consideran esta mala práctica. Sin embargo, las publicaciones que consideran esta mala práctica se han escrito en c # o en algún otro lenguaje de programación, en el que hay algún manejo de errores incorporado. Esta pregunta es sobre c ++. Además, los errores a los que me estoy dirigiendo son errores que son lo suficientemente fatales como para forzar a un programa a cerrarse, no un error general "tal vez haya perdido algo". Con el uso de expresiones en el nivel más alto me refiero a esto en un sentido un poco descuidado. Puede ser algo así como

int main(){
    try {
        //run
    } catch (fatalException){
        //handle error and shutdown
    }
}

o puede ser algo como esto, por ejemplo, en una aplicación gráfica.

void runApplication(){
    try {
        //run
    } catch (fatalException){
        //handle error and shutdown
    }
}

La alternativa a esto sería manejar este error donde ocurra y regresar jerárquicamente de las funciones, una por una hasta que el programa finalice. La razón que puedo ver para terminar con errores fatales por un try-catch en el nivel superior es que las razones para este tipo de error pueden ser diferentes, y es probablemente bastante inusual (bases de datos dañadas, algunos errores de falta de memoria, configuración dañada) archivos, etc ...). El manejo de las excepciones localmente y el retorno de las funciones una por una haría que el código fuera menos claro y requeriría mucho esfuerzo para manejar los problemas que es poco probable que ocurran.

Sin embargo, no estoy seguro de si es una buena práctica iniciar el programa con un try . Personalmente, creo que es feo, pero de alguna manera esta fealdad refleja la fealdad del problema en sí, por lo que puede que no sea una razón para no usarlo en este caso.

EDIT Puede que haya entendido mal la publicación de duplicados, pero no creo que esto resuelva el problema. La pregunta no es sobre no atrapar algunas excepciones. El punto es que en la mayoría de los casos hay otras partes del código que pueden manejar la excepción más cerca del lanzamiento de una manera bastante satisfactoria, pero al costo de tener que pasar por la jerarquía hacia la parte superior y terminar. Sin embargo, dado que el programa aún necesitaría su terminación, ¿hay, en general, alguna razón para detectar antes que en el nivel superior? Se puede argumentar que esto implica que los niveles inferiores no pueden decidir cómo manejar esto. Pero en este caso creo que no está claro. Me refiero a "¿qué error tendría la autoridad para determinar si un programa debe terminar?"

    
pregunta patrik 01.02.2016 - 08:29

2 respuestas

22
  

Tengo una pregunta sobre el uso de excepciones en el nivel más alto de un programa.

     

He visto programas que utilizan esta estrategia y también he visto publicaciones que consideran esta mala práctica.

     

Sin embargo, las publicaciones que consideran esta mala práctica se han escrito en c # o en algún otro lenguaje de programación, donde se ha incorporado algún manejo de errores.

     

Esta pregunta es sobre el c ++.

Los principios del manejo de excepciones [estructurado] son en gran medida independientes del lenguaje.

Cualquiera La excepción no controlada matará tu programa. Lo que están viendo aquí son los controladores de excepciones "backstop" que hacen poco más que registrar la excepción en algún lugar (para que pueda examinarla más adelante) y muestren al usuario un mensaje grande y amigable "Oops", en lugar del desagradable, uno generado

  

La alternativa a esto sería manejar este error donde ocurra y regresar jerárquicamente de las funciones, una por una hasta que el programa finalice.

Esa es una idea terrible.

Use la herramienta correcta para el trabajo correcto.

  • Control de flujo: llamada regular y devolución.
  • Cosas excepcionales que causan estragos - Excepciones.

Tienes la idea de por qué lanzar Excepciones pero creo que te estás perdiendo la parte más importante que es dónde y por qué para atraparlos (o "manejarlos").

Bien, entonces tu base de datos está dañada.
¿Acaba de bloquear el programa?
¿O deja que el usuario, por ejemplo, abra una copia de seguridad de la base de datos?
O abrir el programa es un modo de "diagnóstico" para intentar resolver el problema.

Estas son acciones que su programa puede realizar: formas de "manejar" su CorruptDatabaseException, por ejemplo, si sucede y cuándo sucede.

Sí, las excepciones son ... excepcionales.

No espera que ocurran en una operación normal, pero al crear una Excepción para tal caso, al menos ha pensado en la posibilidad de ello. Sucede y pongo alguna "respuesta" en lugar de lidiar con eso. Bien podría ser que esa acción sea simplemente "cerrar el programa (y decirle al usuario por qué)". En algunos casos, es todo que puede hacer y, para eso, probablemente lo hará el receptor de excepciones Backstop.

  

El punto es que en la mayoría de los casos hay otras partes del código que pueden manejar la excepción más cerca del lanzamiento de una manera bastante satisfactoria, pero al costo de tener que pasar por la jerarquía hacia la parte superior y terminar.

Una vez más, una parte crucial de la Gestión de excepciones es que, después de haber manejado con éxito una Excepción, el resto del programa debe poder continuar como si la Excepción nunca hubiera sucedido . Si su programa no puede hacer eso, entonces la excepción sigue ocurriendo , en cuyo caso debe volver a lanzarla hasta que algo pueda manejarlo (incluso si, eventualmente, eso es solo para terminar el programa).
Este es el principio detrás del bloque "finalmente" visto en C #; El código de "limpieza" en cualquier bloque try-catch que se ejecute automáticamente a medida que la Excepción "lo atraviesa", en su camino hacia arriba a través de la pila de llamadas, en camino a ser manejado.

  

Sin embargo, dado que el programa aún necesitaría su finalización, ¿hay alguna razón para detectar antes en el nivel superior?

Si tuvieras que codificar algo como ...

throw new KillProgramException(); 

... entonces no. La intención es bastante clara y no esperaría nada en su programa para tratar de manejar esto (excepto, quizás, el "respaldo").

  

¿Qué error tendría la autoridad para determinar si un programa debe terminar?

Dependiendo de las circunstancias, ¡podría ser absolutamente cualquiera de ellos!

En alguna sección del código que es muy crítica, una excepción IndexOutOfRangeException podría ser simplemente tan grave como la DatabaseCorruptException.

    
respondido por el Phill W. 01.02.2016 - 13:50
6

Claramente, en su función main () no tiene la oportunidad de manejar la excepción de ninguna manera significativa. Si una excepción llega a main (), todo lo que sabe es que algo salió mal.

Por supuesto, puedes decidir cómo quieres manejar la situación en la que "algo salió mal". Eso no es en absoluto una mala práctica. Por supuesto, puede decidir que maneja esto sin hacer nada (lo que significa que su programa se bloqueará). Puede decidir manejar esto diciéndole al usuario que algo salió mal y luego salir. Dependiendo del entorno, ya sea mejor o peor que un simple fallo (en una aplicación iOS, se consideraría peor). Puede decidir manejar esto guardando lo que se puede guardar y luego salir; esto es algo que se debe hacer muy cuidadosamente porque sabes que algo simplemente salió mal. O puede decidir mantener su aplicación en ejecución, lo que también debe hacerse con mucho cuidado porque sabe que algo simplemente salió mal.

Resumen: No es una mala práctica. Debería ser una decisión consciente, y detectar el error en este nivel debería agregar algo de valor. Una captura de este punto que no hace nada es obviamente inútil, pero tampoco hace ningún daño. Así que podría hacerme preguntarme "por qué el desarrollador está haciendo eso", pero no duele.

Debería manejarlo antes: si una excepción es algo que usted sabe cómo manejar, entonces obviamente la maneja. Si sabe que una excepción solo puede ser ignorada, ignórela. Si no sabe cómo manejarlo y no sabe que se puede ignorar, decida cómo manejarlo o descubra que puede ignorarlo o no lo atrape porque tal excepción significa "algo salió mal". Y si realmente sabe que no puede manejar una excepción porque simplemente significa que "algo salió mal", entonces tampoco lo detecte.

    
respondido por el gnasher729 01.02.2016 - 11:28

Lea otras preguntas en las etiquetas