¿Por qué el manejo de excepciones es malo?

90

El lenguaje Go de Google no tiene excepciones como elección de diseño, y Linus, de Linux, ha llamado a las excepciones una mierda. ¿Por qué?

joemoe
fuente
2
El creador de ZeroMQ escribe sobre cómo cree que fue un error escribirlo en C ++ (principalmente debido al manejo de errores) 250bpm.com/blog:4
serbaut
Es posible que Go no tenga excepciones, pero tiene "pánicos" de los que puede "recuperarse" (mientras las declaraciones diferidas aún se ejecutan) y que proporcionan un flujo de control no local ...
Kerrek SB
Aquí hay un buen artículo lighterra.com/papers/exceptionsharmful (manejo de excepciones considerado dañino)
masterxilo
Afaics, las excepciones se pueden simular en Go con un texto estándar significativo , aunque este punto puede ser más significativo para la transpilación de un azúcar de sintaxis que para escribir el texto estándar manualmente.
Shelby Moore III

Respuestas:

83

Las excepciones hacen que sea realmente fácil escribir código donde una excepción que se lanza romperá invariantes y dejará los objetos en un estado inconsistente. Básicamente, te obligan a recordar que casi todas las declaraciones que haces pueden arrojar y manejar eso correctamente. Hacerlo puede ser complicado y contrario a la intuición.

Considere algo como esto como un ejemplo simple:

class Frobber
{
    int m_NumberOfFrobs;
    FrobManager m_FrobManager;

public:
    void Frob()
    {
        m_NumberOfFrobs++;

        m_FrobManager.HandleFrob(new FrobObject());
    }
};

Suponiendo que la FrobManagervoluntad deletedel FrobObject, esto se ve bien, ¿verdad? O tal vez no ... Imagínense entonces si FrobManager::HandleFrob()o operator newlanza una excepción. En este ejemplo, el incremento de m_NumberOfFrobsno se revierte. Por lo tanto, cualquiera que use esta instancia de Frobbertendrá un objeto posiblemente dañado.

Este ejemplo puede parecer estúpido (ok, tuve que estirarme un poco para construir uno :-)), pero la conclusión es que si un programador no está pensando constantemente en excepciones y asegurándose de que cada permutación de estado se lleve a cabo siempre que hay lanzamientos, te metes en problemas de esta manera.

Como ejemplo, puede pensar en ello como si pensara en mutex. Dentro de una sección crítica, confía en varias declaraciones para asegurarse de que las estructuras de datos no estén dañadas y que otros subprocesos no puedan ver sus valores intermedios. Si alguna de esas declaraciones simplemente no se ejecuta al azar, terminará en un mundo de dolor. Ahora elimine los bloqueos y la concurrencia, y piense en cada método de esa manera. Piense en cada método como una transacción de permutaciones en el estado del objeto, por así decirlo. Al comienzo de la llamada al método, el objeto debe tener un estado limpio y, al final, también debe haber un estado limpio. En el medio, la variable foopuede ser inconsistente conbar, pero su código eventualmente lo rectificará. Lo que significan las excepciones es que cualquiera de sus declaraciones puede interrumpirlo en cualquier momento. La responsabilidad recae en usted en cada método individual para hacerlo bien y retroceder cuando eso suceda, u ordenar sus operaciones para que los lanzamientos no afecten el estado del objeto. Si se equivoca (y es fácil cometer este tipo de error), la persona que llama termina viendo sus valores intermedios.

Los métodos como RAII, que a los programadores de C ++ les encanta mencionar como la solución definitiva a este problema, ayudan en gran medida a protegerse contra esto. Pero no son una solución milagrosa. Se asegurará de que libere recursos en un lanzamiento, pero no lo liberará de tener que pensar en la corrupción del estado del objeto y en los llamadores que ven valores intermedios. Entonces, para mucha gente, es más fácil decirlo, por orden del estilo de codificación, sin excepciones . Si restringe el tipo de código que escribe, es más difícil introducir estos errores. Si no lo hace, es bastante fácil cometer un error.

Se han escrito libros completos sobre codificación segura de excepciones en C ++. Muchos expertos se han equivocado. Si es realmente tan complejo y tiene tantos matices, tal vez sea una buena señal de que debes ignorar esa característica. :-)

asveikau
fuente
9
Interesante respuesta, sin embargo, no refleja nada en mi experiencia de programación. Así que supongo que es específico de la cultura (tal vez un problema mayor en Java o C ++ que, digamos, Python) o específico del dominio.
ddaa
42
Las excepciones escritas en un lenguaje administrado usando un patrón try-catch-finalmente nunca deben dejar un estado no válido si están escritas correctamente; dado que se garantiza que el bloque finalmente se ejecutará, los objetos se pueden desasignar allí. El resto debe ser atendido por variables que salgan del alcance y recolección de basura.
Robert Harvey
7
@ddaa El problema es definitivamente posible en Python. El resultado suele ser un error difícil de reproducir. Quizás ha sido especialmente meticuloso o afortunado. Pero entonces, tiene razón en que es más un problema en C ++, donde el error más común de EH pobre es una pérdida de memoria. Traté de enfatizar que las fugas no son el problema más serio. @Robert GC mitigará las pérdidas de memoria, pero no estoy seguro de que el código administrado lo libere del error del programador. En particular, si alguien no está prestando atención a la seguridad de las excepciones porque no cree que sea un problema en su idioma, esa no es una buena señal.
asveikau
4
@lzprgmr ciertamente las hay: las excepciones le permiten lidiar con diff. tipos de errores en diff. lugares en el código. Tratar con un error de conexión puede requerir una reconexión, pero no en medio de una función profundamente anidada. Quieres decirle eso al administrador de conexiones o algo así. Luego, lidiar con los valores devueltos lo obliga a verificar los errores en cada llamada individual y agregarlos manualmente (en el caso de un error de restablecimiento de conexión, por ejemplo). Además, los valores de retorno se acumulan en llamadas anidadas: func3 puede devolver -1, func2 llama a func3, devuelve -2 en sus errores, -1 para func3, etc.
abourget
4
Yo estaba votando en contra, pero lo revoqué porque esta es una razón por la que se desprecian las excepciones. Sin embargo, en mi opinión, casi cualquier método o código puede fallar. No puede manejar cada condición de error introduciendo un valor de retorno para ella. Perderá información sobre el error. Pensar que puede mantener todo bien sincronizado verificando todas y cada una de las declaraciones y haciendo la limpieza conduce a un código muy complicado: detectar un error en varias declaraciones y limpiar uno o dos recursos que no están GC'ed es mucho más limpio.
Maarten Bodewes
50

El motivo por el que Go no tiene excepciones se explica en las preguntas frecuentes sobre el diseño del lenguaje de Go:

Las excepciones son una historia similar. Se han propuesto varios diseños para excepciones, pero cada uno agrega una complejidad significativa al lenguaje y al tiempo de ejecución. Por su propia naturaleza, las excepciones abarcan funciones y quizás incluso gorutinas; tienen implicaciones de amplio alcance. También existe preocupación por el efecto que tendrían en las bibliotecas. Son, por definición, excepcionales, pero la experiencia con otros lenguajes que los soportan demuestra que tienen un efecto profundo en la especificación de la biblioteca y la interfaz. Sería bueno encontrar un diseño que les permita ser realmente excepcionales sin alentar los errores comunes a convertirse en un flujo de control especial que requiere que cada programador lo compense.

Al igual que los genéricos, las excepciones siguen siendo un tema abierto.

En otras palabras, aún no han descubierto cómo admitir excepciones en Go de una manera que consideren satisfactoria. No están diciendo que las Excepciones sean malas per se ;

ACTUALIZACIÓN - Mayo de 2012

Los diseñadores de Go ahora se han bajado de la valla. Sus preguntas frecuentes ahora dicen esto:

Creemos que acoplar excepciones a una estructura de control, como en el idioma try-catch-finalmente, da como resultado un código complicado. También tiende a alentar a los programadores a etiquetar demasiados errores comunes, como no abrir un archivo, como excepcionales.

Go adopta un enfoque diferente. Para el manejo sencillo de errores, las devoluciones de valores múltiples de Go facilitan la notificación de un error sin sobrecargar el valor devuelto. Un tipo de error canónico, junto con otras características de Go, hace que el manejo de errores sea agradable pero bastante diferente al de otros idiomas.

Go también tiene un par de funciones integradas para señalar y recuperarse de condiciones verdaderamente excepcionales. El mecanismo de recuperación se ejecuta solo como parte del estado de una función que se elimina después de un error, lo cual es suficiente para manejar una catástrofe pero no requiere estructuras de control adicionales y, cuando se usa bien, puede resultar en un código limpio de manejo de errores.

Consulte el artículo Aplazar, entrar en pánico y recuperar para obtener más detalles.

Entonces, la respuesta corta es que pueden hacerlo de manera diferente utilizando el retorno de múltiples valores. (Y de todos modos tienen una forma de manejo de excepciones).


... y Linus de Linux ha llamado a las excepciones una mierda.

Si quieres saber por qué Linus piensa que las excepciones son una mierda, lo mejor es buscar sus escritos sobre el tema. Lo único que he rastreado hasta ahora es esta cita que está incrustada en un par de correos electrónicos en C ++ :

"Todo el asunto del manejo de excepciones de C ++ está fundamentalmente roto. Está especialmente roto para los núcleos".

Notarás que está hablando de excepciones de C ++ en particular, y no de excepciones en general. (Y excepciones de C ++ no tienen aparentemente algunas cuestiones que los hacen difíciles de usar correctamente).

¡Mi conclusión es que Linus no ha llamado a las excepciones (en general) "basura" en absoluto!

Esteban C
fuente
30
Odio cuando ocultan información poniéndola en las preguntas frecuentes. :)
brian d foy
7
Tenga en cuenta que Linus comienza ese correo electrónico con "C ++ es un lenguaje horrible". y continúa despotricando sobre lo mucho que odia tanto a C ++ como a las personas que eligen programar en él. En consecuencia, no creo que su opinión sobre las excepciones de C ++ pueda considerarse confiable dada su opinión algo sesgada hacia C ++.
Pharap
1
@ Hi-Angel - Como dice el texto que cité: "Para el manejo simple de errores, las devoluciones de valores múltiples de Go facilitan informar un error sin sobrecargar el valor devuelto". . Así es como se relaciona. De cualquier manera, estoy citando la lógica de los diseñadores de Go. Si quiere discutir, discuta con ellos >>.
Stephen C
1
@ Hi-Angel - Yo no escribí esos párrafos. Simplemente los cité. Si tiene algún problema con ellos, probablemente debería hablar con los autores. En teoría, podría haber proporcionado un tutorial sobre el lenguaje Go como contexto. Pero, para ser sincero, las personas que no comprenden la terminología de Go pueden visitar el sitio web de Go para descubrir qué significa.
Stephen C
1
"... da como resultado un código complicado" Hace mucho tiempo que escribí un programa en C con muchas operaciones de cadena. Cada método fue asignar memoria y luego verificar si la asignación fue exitosa. Parecía que la mayor parte del código solo estaba verificando asignaciones. ¿No es complicado? C ++ con excepciones fue un gran rescate para mí.
robsosno
29

Las excepciones no son malas en sí mismas, pero si sabe que van a suceder con frecuencia, pueden resultar caras en términos de rendimiento.

La regla general es que las excepciones deben marcar las condiciones excepcionales y que no debe utilizarlas para controlar el flujo del programa.

Robert Harvey
fuente
9
@Robert: "no deberías usarlos para controlar el flujo del programa", no lo he pensado de esta manera, nueva perspectiva para mí: P +1
okw
2
También realmente depende del idioma. Es difícil evitar excepciones si está programando en Java, por ejemplo.
Charles Salvia
2
@Charles: Creo que el punto es que las excepciones son apropiadas en situaciones que indican un error, un sistema mal configurado o entradas no razonables. La mayoría de las excepciones de la biblioteca de Java se pueden evitar en el código de "flujo de trabajo normal".
Artelius
6
no tienen que costar mucho. por ejemplo, puede implementar un "intento" que cueste un tiempo de ejecución cero y hacer que "lanzar" busque controladores de excepciones en una tabla según las direcciones de las personas que llaman que ve en la pila ... Yo diría que las principales razones para no las excepciones de uso no están relacionadas en absoluto con el rendimiento.
asveikau
Reformulado; la pregunta sugiere claramente el uso de excepciones en general, o no usar excepciones en absoluto (son una mierda o ni siquiera están en el idioma). Su respuesta solo muestra por qué las excepciones son malas para el rendimiento cuando se utilizan para el flujo de control del programa.
Maarten Bodewes
26

No estoy de acuerdo con "lanzar excepciones únicamente en una situación excepcional". Aunque en general es cierto, es engañoso. Las excepciones son para condiciones de error (fallas de ejecución).

Independientemente del idioma que utilice, obtenga una copia de las Pautas de diseño del marco : convenciones, expresiones idiomáticas y patrones para bibliotecas .NET reutilizables (segunda edición). El capítulo sobre lanzamiento de excepciones no tiene parangón. Algunas citas de la primera edición (la segunda en mi trabajo):

  • NO devuelva códigos de error.
  • Los códigos de error se pueden ignorar fácilmente, y a menudo lo son.
  • Las excepciones son el medio principal de informar errores en los marcos.
  • Una buena regla general es que si un método no hace lo que sugiere su nombre, debe considerarse una falla a nivel de método, lo que resulta en una excepción.
  • NO utilice excepciones para el flujo normal de control, si es posible.

Hay páginas de notas sobre los beneficios de las excepciones (consistencia API, elección de la ubicación del código de manejo de errores, robustez mejorada, etc.) Hay una sección sobre rendimiento que incluye varios patrones (Tester-Doer, Try-Parse).

Las excepciones y el manejo de excepciones no están mal. Como cualquier otra función, se pueden utilizar incorrectamente.

TrueWill
fuente
4
Tengo que estar en desacuerdo con eso. No estoy en contra de las excepciones, y ese libro es imprescindible, sin embargo, está sesgado hacia el desarrollo de .NET y C #.
3
Sé que esto es antiguo, solo quería comentar que parece que habría un desacuerdo de estilo general entre el tipo .NET y el tipo * nix. Todas las bibliotecas que he usado como desarrollador de Linux usan códigos de retorno, y las guías de estilo * nix que he leído (como las de mi empresa y las de Google, por ejemplo) simplemente dicen "no hacemos excepciones". Piensa que es interesante.
jarvisteve
1
Los marcos deben tratar las excepciones de manera diferente a las aplicaciones de usuario final. Los marcos no tienen una forma de lidiar con los errores más que lanzar una excepción, las aplicaciones de consumo sí.
0x6C38
11

Desde la perspectiva de golang, supongo que no tener un manejo de excepciones mantiene el proceso de compilación simple y seguro.

Desde la perspectiva de Linus, entiendo que el código del kernel es TODO sobre casos de esquina. Por tanto, tiene sentido rechazar las excepciones.

Las excepciones tienen sentido en el código donde está bien dejar la tarea actual en el piso y donde el código de caso común tiene más importancia que el manejo de errores. Pero requieren la generación de código del compilador.

Por ejemplo, están bien en la mayoría de los códigos de alto nivel orientados al usuario, como el código de aplicaciones web y de escritorio.

ddaa
fuente
Pero lo que es cierto para el código del kernel también lo es para los procesos de servidor nativo de larga ejecución.
Lothar
11

Las excepciones en sí mismas no son "malas", es la forma en que a veces se manejan las excepciones lo que tiende a ser malo. Hay varias pautas que se pueden aplicar al manejar excepciones para ayudar a aliviar algunos de estos problemas. Algunos de estos incluyen (pero seguramente no se limitan a):

  1. No utilice excepciones para controlar el flujo del programa, es decir, no confíe en las declaraciones "catch" para cambiar el flujo de la lógica. Esto no solo tiende a ocultar varios detalles en torno a la lógica, sino que puede conducir a un rendimiento deficiente.
  2. No arroje excepciones desde dentro de una función cuando un "estado" devuelto tendría más sentido; solo arroje excepciones en una situación excepcional. La creación de excepciones es una operación costosa que requiere un alto rendimiento. Por ejemplo, si llama a un método para abrir un archivo y ese archivo no existe, lance una excepción "FileNotFound". Si llama a un método que determina si existe una cuenta de cliente, devuelve un valor booleano, no devuelve una excepción "CustomerNotFound".
  3. Al determinar si manejar o no una excepción, no use una cláusula "try ... catch" a menos que pueda hacer algo útil con la excepción. Si no puede manejar la excepción, debe dejar que burbujee en la pila de llamadas. De lo contrario, el controlador puede "tragarse" las excepciones y los detalles se perderán (a menos que vuelva a lanzar la excepción).
Jeff Bramwell
fuente
2
Devolver el estado es algo complicado. He visto demasiado código que tiene un método GetCustomer que devuelve una entidad Cliente en caso de éxito o nula en caso de error. En varios casos, el código de llamada nunca verificó el resultado, pero inmediatamente accedió al Cliente. Esto funcionó la mayor parte del tiempo ...
TrueWill
3
Pero si GetCustomer lanza una excepción en lugar de devolver un valor nulo, el código del cliente aún necesita manejar la excepción. Ya sea verificando nulos o manejando excepciones, la responsabilidad recae en el código del cliente; si no hace las cosas correctamente, tarde o temprano algo explotará.
Chris
1
@TrueWill Los lenguajes que admiten plantillas / genéricos resuelven esto devolviendo un en Option<T>lugar de nullhoy en día. Acabo de introducirlo en Java 8, por ejemplo, siguiendo una pista de Guava (y otros).
Maarten Bodewes
@owlstead Sí. Me encanta la mónada tal vez. Esa es una buena forma de hacerlo si su idioma lo admite y ofrece coincidencia de patrones.
TrueWill
@owlstead Una vez más, lo que Chris dijo todavía es válido para eso: el usuario debe recordar llamar a la función .orElse (defaultObject), o cualquier idioma que haya decidido el idioma en cuestión. Al final del día, son los programadores los que son el problema, más que el método de manejo de errores.
Pharap
9

Los argumentos típicos son que no hay forma de saber qué excepciones saldrán de un fragmento de código en particular (dependiendo del lenguaje) y que se parecen demasiado a gotos, lo que dificulta el seguimiento mental de la ejecución.

http://www.joelonsoftware.com/items/2003/10/13.html

Definitivamente no hay consenso sobre este tema. Yo diría que desde el punto de vista de un programador de C de núcleo duro como Linus, las excepciones son definitivamente una mala idea. Sin embargo, un programador típico de Java se encuentra en una situación muy diferente.

Tim Sylvester
fuente
1
El código C tiene algunas excepciones, solo que de una manera diferente. ¡Debe envolver cada llamada a una función no trivial en ifs, lo que hace que usar ese lenguaje sea un dolor de cabeza!
RCIX
1
También está el setjmp/ longjmpstuff, que es bastante malo.
Tim Sylvester
9
¿De verdad quieres seguir el consejo de un hombre que valora a los programadores de Duct Tape y que no cree que las pruebas unitarias sean necesarias? joelonsoftware.com/items/2009/09/23.html
TrueWill
4
Este es un error (o trampa) clásico en una discusión donde los argumentos sobre el tema se reemplazan con referencias de personalidad. Eso suele ser una señal de una discusión degenerada.
Petr Gladkikh
1
@PetrGladkikh La discusión comenzó con el OP refiriéndose a la opinión de Linus ... que el engaño se conoce como la falacia de apelar a la autoridad. La discusión solo puede ir cuesta arriba a partir de ahí, y no es "trampa" responder la pregunta de por qué a Linus no le gustan las excepciones refiriéndose a su personalidad.
Jim Balter
7

Las excepciones no son malas. Encajan bien con el modelo RAII de C ++, que es lo más elegante de C ++. Si ya tiene un montón de código que no es seguro para excepciones, entonces son malos en ese contexto. Si está escribiendo software de muy bajo nivel, como el sistema operativo Linux, entonces son malos. Si le gusta ensuciar su código con un montón de comprobaciones de devolución de errores, entonces no son útiles. Si no tiene un plan para el control de recursos cuando se lanza una excepción (que proporcionan los destructores de C ++), entonces son malos.

Paul
fuente
7
RAII es útil incluso sin excepciones.
Mark Ransom
4
sin embargo, las excepciones no son útiles sin RAII (o alguna otra administración automática de recursos).
Greg Rogers
+1 para señalar situaciones en las que las excepciones no son apropiadas y que las excepciones no son inherentemente malas.
Pharap
4

Por lo tanto, un gran caso de uso para las excepciones es ...

Supongamos que está en un proyecto y cada controlador (alrededor de 20 principales diferentes) extiende un solo controlador de superclase con un método de acción. Luego, cada controlador hace un montón de cosas diferentes entre sí, llamando a los objetos B, C, D en un caso y F, G, D en otro caso. Las excepciones vienen al rescate aquí en muchos casos donde había toneladas de códigos de retorno y CADA controlador lo manejaba de manera diferente. Golpeé todo ese código, arrojé la excepción adecuada de "D", lo atrapé en el método de acción del controlador de superclase y ahora todos nuestros controladores son consistentes. Anteriormente, D devolvía nulo para MÚLTIPLES casos de error diferentes de los que queremos informar al usuario final, pero no pude y yo no '

sí, tenemos que preocuparnos por cada nivel y cualquier limpieza / fuga de recursos, pero en general ninguno de nuestros controladores tuvo recursos para limpiar después.

gracias a Dios tuvimos excepciones o habría tenido una gran refactorización y habría perdido demasiado tiempo en algo que debería ser un simple problema de programación.

Dean Hiller
fuente
1
+1 Fácilmente uno de los mejores argumentos para usar excepciones que he leído. Podría haber usado ejemplos más detallados (es decir, un diagrama UML, algún pseudocódigo o algún código real) pero el punto acerca de hacer que las subclases funcionen consistentemente es bueno. Además, el hecho de que su evidencia sea anecdótica muestra que las excepciones son útiles en situaciones reales y la utilidad es el propósito principal de cualquier característica del lenguaje.
Pharap
solo como una adición, si está en scala, puede devolver Try [ResponseType] que representa una excepción o respuesta real. A continuación, puede seguir el mismo patrón que eludí anteriormente sin excepciones reales aparte de las que se ponen en el intento. Entonces es como si cada método que tiene devuelve 1 + n tipos de respuesta que creo que es necesario. Sin embargo, en scala devolvemos Future [response] que funciona de manera muy similar a Try, pero puede ayudar con una programación más asincrónica.
Dean Hiller
2

Teóricamente son realmente malos. En el mundo matemático perfecto no se pueden encontrar situaciones excepcionales. Mire los lenguajes funcionales, no tienen efectos secundarios, por lo que prácticamente no tienen fuente para situaciones excepcionales.

Pero la realidad es otra historia. Siempre tenemos situaciones que son "inesperadas". Por eso necesitamos excepciones.

Creo que podemos pensar en excepciones como el azúcar de sintaxis para ExceptionSituationObserver. Solo recibe notificaciones de excepciones. Nada mas.

Con Go, creo que introducirán algo que se ocupará de situaciones "inesperadas". Puedo suponer que intentarán que suene menos destructivo como excepciones y más como lógica de aplicación. Pero esto es solo mi suposición.

Mike Chaliy
fuente
2
"Mire los lenguajes funcionales, no tienen efectos secundarios, por lo que virtualmente no tienen fuente para situaciones no excepcionales". Eso es una exageración enorme.
Stephen C
3
¿Qué es 5/0 en matemáticas? Arcsin (200)? Sqrt (-1)? Las matemáticas tienen muchas situaciones excepcionales.
Robert Fraser
3
Estas no son situaciones excepcionales ... simplemente no tienen significado ... y por eso podrían implementarse como excepciones ... pero también podrían implementarse como vialaciones de condiciones previas ... así que depende de la implementación técnica.
Mike Chaliy
3
@MikeChaliy - Lo siento, pero eso es solo sofisma. Puede aplicar ese tipo de razonamiento para decir que NO hay situaciones de excepción en nada, NUNCA. En realidad, las expresiones matemáticas que no tienen significado (o que no tienen un valor definido) SON excepcionales. Esto no significa que deban tratarse lanzando y capturando excepciones ... pero si no lo hace, necesita valores especiales (como Inf y Nan) u operaciones que devuelvan múltiples valores. En resumen, estos casos requieren algún tipo de tratamiento especial.
Stephen C
1
Las computadoras son máquinas de estado. No es un mundo matemático perfecto.
Arunav Sanyal
1

El paradigma de manejo de excepciones de C ++, que forma una base parcial para el de Java, y a su vez .net, introduce algunos buenos conceptos, pero también tiene algunas limitaciones severas. Una de las intenciones clave del diseño del manejo de excepciones es permitir métodos para garantizar que satisfagan sus condiciones posteriores o lanzar una excepción, y también garantizar que se lleve a cabo cualquier limpieza que deba realizarse antes de que un método pueda salir. Desafortunadamente, los paradigmas de manejo de excepciones de C ++, Java y .net no brindan ningún medio adecuado para manejar la situación en la que factores inesperados impiden que se realice la limpieza esperada. Esto, a su vez, significa que uno debe arriesgarse a que todo se detenga de golpe si sucede algo inesperado (el enfoque de C ++ para manejar una excepción ocurre durante el desenrollado de la pila),

Incluso si el manejo de excepciones en general sería bueno, no es descabellado considerar inaceptable un paradigma de manejo de excepciones que no proporciona un buen medio para manejar los problemas que ocurren al limpiar después de otros problemas. Eso no quiere decir que no se pueda diseñar un marco con un paradigma de manejo de excepciones que pueda garantizar un comportamiento sensato incluso en escenarios de fallas múltiples, pero ninguno de los principales lenguajes o marcos todavía puede hacerlo.

Super gato
fuente
1

No he leído todas las otras respuestas, por lo que es posible que esto ya se haya mencionado, pero una crítica es que hacen que los programas se rompan en largas cadenas, lo que dificulta la localización de errores al depurar el código. Por ejemplo, si Foo () llama a Bar () que llama a Wah () que llama a ToString () y luego accidentalmente empujar los datos incorrectos en ToString () termina pareciendo un error en Foo (), una función casi completamente no relacionada.

kingfrito_5005
fuente
0
  • La excepción que no se maneja es generalmente mala.
  • La excepción manejada mal es mala (por supuesto).
  • La 'bondad / maldad' del manejo de excepciones depende del contexto / alcance y la idoneidad, y no por el simple hecho de hacerlo.
OK W
fuente
0

Bien, respuesta aburrida aquí. Supongo que realmente depende del idioma. Cuando una excepción puede dejar atrás los recursos asignados, deben evitarse. En los lenguajes de secuencias de comandos, simplemente abandonan o sobrepasan partes del flujo de la aplicación. Eso es desagradable en sí mismo, pero escapar de errores casi fatales con excepciones es una idea aceptable.

Para la señalización de errores, generalmente prefiero las señales de error. Todo depende de la API, el caso de uso y la gravedad, o si el registro es suficiente. También estoy tratando de redefinir el comportamiento y en su throw Phonebooks()lugar. La idea es que las "Excepciones" son a menudo callejones sin salida, pero una "Agenda telefónica" contiene información útil sobre la recuperación de errores o rutas de ejecución alternativas. (Todavía no se ha encontrado un buen caso de uso, pero sigue intentándolo).

mario
fuente
0

Para mi el tema es muy sencillo. Muchos programadores usan el manejador de excepciones de manera inapropiada. Más recursos lingüísticos es mejor. Ser capaz de manejar excepciones es bueno. Un ejemplo de mal uso es un valor que debe ser un número entero y no ser verificado, u otra entrada que puede dividir y no verificarse para la división de cero ... el manejo de excepciones puede ser una manera fácil de evitar más trabajo y pensar mucho, el programador puede querer hacer un atajo sucio y aplicar un manejo de excepciones ... La declaración: "un código profesional NUNCA falla" puede ser ilusoria, si algunos de los problemas procesados ​​por el algoritmo son inciertos por su propia naturaleza. Quizás en las situaciones desconocidas por naturaleza sea bueno que entre en juego el manejador de excepciones. Las buenas prácticas de programación son materia de debate.

iuri
fuente
El problema no es (o no debería ser) si el código puede fallar; un problema mayor es hasta qué punto, si el código falla, uno se preocupa por los detalles. Si uno intenta cargar un documento y uno de los métodos de "lectura de datos" falla, a menudo no le importa cuál, ya que el efecto es el mismo independientemente: el documento no se puede cargar. Conceptualmente, el manejo de excepciones debería ser bueno para eso. El problema es que los paradigmas de manejo de excepciones de .NET y Java no proporcionan ninguna forma agradable de distinguir las excepciones "aburridas" que deberían agruparse, de aquellas que no deberían.
supercat