¿Usando aserciones versus lanzando excepciones?

38

A menudo, cuando escribo una función, quiero asegurarme de que las entradas sean válidas para detectar dichos errores lo antes posible (creo que se denominan condiciones previas). Cuando falla una condición previa, siempre he lanzado una excepción. Pero estoy empezando a dudar si esta es la mejor práctica y si no, las afirmaciones serían más apropiadas.

Entonces, ¿cuándo debo hacer qué? ¿Cuándo es apropiado usar una aserción y cuándo es apropiado lanzar una excepción?

gablin
fuente
3
Creo que esta pregunta debería hacerse en stackoverflow, aunque probablemente se haya hecho una docena de veces allí, por lo que es posible que ya encuentre muchas respuestas allí.
usuario281377

Respuestas:

50

Las afirmaciones solo deben usarse para verificar condiciones que lógicamente deberían ser imposibles de ser falsas (léase: controles de cordura). Estas condiciones solo deben basarse en las entradas generadas por su propio código. Cualquier verificación basada en entradas externas debe usar excepciones.

Una regla simple que tiendo a seguir es verificar los argumentos de las funciones privadas con afirmaciones, y usar excepciones para los argumentos de funciones públicas / protegidas.

Nota para uno mismo - piense en un nombre
fuente
Buen punto sobre el uso de excepciones para entradas externas. También agregaría resultados a eso también: problemas al intentar crear / escribir en un archivo / base de datos, etc.
ChrisF
13
E inevitablemente encontrará que esas afirmaciones se activan en la producción. ¡+1 para verificar cosas privadas con afirmaciones! ¿Tal vez podría decir "use aserts cuando tenga el control total de las entradas"?
Frank Shearar
1
En java, al menos, normalmente debe habilitar la verificación de aserciones con el parámetro de línea de comando -ea. Esto significa que las afirmaciones son efectivamente no operativas, a menos que las active explícitamente.
Bill Michell
29

Las aserciones se utilizan para encontrar errores de programación. Sus programas deben funcionar igual de bien cuando se eliminan todas las aserciones.

Las excepciones, por otro lado, son para situaciones que pueden ocurrir incluso cuando el programa es perfecto; son causados ​​por influencias externas, como hardware, red, usuarios, etc.

usuario281377
fuente
Esta es una muy buena manera de decirlo. Si el usuario ingresa algo incorrecto, arroje una excepción. Si la entrada es correcta pero algo sigue mal, lanza una afirmación.
Mateen Ulhaq
3

La práctica de programación típica es compilar aserciones de compilaciones de producción / lanzamiento. Las afirmaciones ayudarán solo durante las pruebas internas para detectar el fracaso de los supuestos. No debe asumir el comportamiento de agencias externas, por lo que no debe hacer valer los eventos de la red o del usuario. También es una buena práctica escribir código de manejo para compilaciones de producción en caso de que falle una aserción.

Por ejemplo en C,

int printf(const char *fmt, ...)
{
  assert(fmt);  // may fail in debug build but not in production build
  if (!fmt) return -1; // handle gracefully in production build
  ...
}

Las excepciones están destinadas a integrarse en las compilaciones de producción. La alternativa para la excepción es devolver un error y no afirmaciones.

aufather
fuente
2
No creo que sea una buena idea poner un comportamiento elegante detrás de una afirmación para la misma condición. Inevitablemente, debido a que el comportamiento elegante solo existe en la versión de producción, el código que se suponía que trataría con el comportamiento elegante se probará mal y se bloqueará tan mal como, si no es que peor, si el código no estuviera protegido.
Sebastian Redl
0

Un problema con afirmaciones para mí es que están deshabilitadas por defecto en Java.

Usamos una estrategia de falla en la que el programa, que puede haber estado funcionando sin supervisión durante años, debe bloquearse lo antes posible para evitar la corrupción de datos en caso de datos incorrectos (en un formulario inesperado). Esto es para lo que usamos la verificación, y al usar afirmaciones básicamente nos arriesgamos a que no estén activos.


fuente