validation exception

validation - ¿Es una buena o mala idea arrojar Excepciones al validar datos?



exception (12)

Al validar los datos, he adquirido el hábito de hacer lo siguiente

* Nota: realmente no tengo booleanos individuales para cada cheque. Esto es solo por el ejemplo.

* Otra nota: cualquier manejo de errores durante las pruebas se realiza correctamente. Las ÚNICAS excepciones lanzadas en el try-catch son mías.

Try { if(validCheckOne = false) { throw new Exception("Check one is bad"); } if(validCheckTwo = false) { throw new Exception("Fail''D because of check2"); } if(validCheckTen = false) { throw new Exception("Yet another failure on your part: check10."); } } catch(Exception e) { MessageBox.Show("Your stupid data is wrong! See for yourself: " + e.Message); }

¿Es esta mala práctica? ¿Lanzando Excepciones ralentiza la ejecución del programa o es desaconsejable?


Además de la afirmación frecuentemente repetida de que "las excepciones son por circunstancias excepcionales", aquí hay una regla aclaratoria adicional que me gusta:

Si el usuario lo causó, no es excepcional.

Las excepciones son para cosas del sistema (servidores que están cayendo, recursos no disponibles), no para el usuario que hace cosas raras, porque todos los usuarios hacen cosas raras.


Apoyo la respuesta de MusiGenesis.

Adicionalmente...

La realización de arrojar una excepción es un millar de instrucciones. No es nada comparado con el tiempo del usuario final, pero en el código interno es lento.

Un problema adicional es que, al usar Excepciones, su validación se limita a informar el primer error (y tendrá que volver a hacerlo todo la próxima vez para encontrar el siguiente error).


Así que, tal vez, en algunos idiomas, el lanzamiento y la captura son "costosos", pero en otros idiomas, lanzar y atrapar excepciones es exactamente lo que se necesita.

En Smalltalk, por ejemplo, uno podría construir rápidamente una solución de captura de excepción de varios niveles. El pase de validación podría acumular cualquier número de excepciones que representen TODO lo que está mal con un conjunto de datos de entrada en particular. Luego los lanzaría TODOS hasta un receptor de nivel superior, responsable de formatear una explicación legible para humanos, de nuevo, TODO lo que estaba mal con la entrada. A su vez arrojaría una única excepción más arriba en la cadena, junto con esa explicación formateada.

Entonces ... supongo que lo que estoy diciendo es que las excepciones son malas para tirar si no tienes una arquitectura de manejo de excepción que apoye la captura de ellos y hacer cosas razonables con ellos, y todo lo que tu catcher hará es SALIR o hacer algo más igualmente inapropiado.


Depende - si espera que los datos estén allí y NO tener los datos es inesperado, entonces lanzar una excepción está bien. Lanzar una excepción es muy costoso (lento) pero es la mejor manera de manejar circunstancias inesperadas.


En el título lo llamas datos de "validación". Eso puede suceder en varios niveles. En (cerca de) la GUI en la que está comprobando datos ingresados ​​por el usuario, debe esperar errores y formas de informar los errores. Las excepciones son inapropiadas en este caso.

Pero la validación de datos también puede ocurrir en otros límites, por ejemplo, entre clases de reglas de negocio. Allí, los errores en los datos son poco comunes e inesperados. Debes lanzar cuando detectes uno.


En general, estoy de acuerdo con la regla de "excepciones debe ser excepcional", pero podría hacer una excepción (¡ja!) Para Python, donde puede ser tanto eficiente como una buena práctica considerar usar ... excepto para controlar el flujo.

Consulte Uso de excepciones para otros fines , por ejemplo.


En general, no es aconsejable usar Excepciones para implementar flujo condicional. Sería mejor hacer algo como esto

error = false; while(true) { if(validCheckOne == false) { msg = "Check one is bad"; error = true; break; } if(validCheckTwo == false) { msg = "Check two is bad"; error = true; break; } ... break; } if (error) { .. }

Debes lanzar una excepción cuando hay una situación en la que no puedes hacer nada al respecto. Las capas más altas de software tendrían la posibilidad de detectar la excepción y hacer algo al respecto, incluso si eso simplemente está bloqueando la aplicación.


Esto es mal comportamiento. Las excepciones son para condiciones excepcionales . Toman recursos para generar la pila, etc. Las excepciones no se deben usar para dictar el flujo del proceso.


Personalmente, me gusta lanzar Excepciones para la validación de reglas de negocio (no tanto para la validación de entrada del usuario) porque obliga a manejar el problema en sentido ascendente. Si mis objetos comerciales devolvían algún tipo de resultado de validación, la persona que llama podría ignorarlo. Llámame un vaquero si lo deseas :)

Todos aquí están repitiendo la frase "las excepciones son por circunstancias excepcionales", pero eso realmente no da ninguna explicación de por qué es malo usarlas para circunstancias excepcionales. Necesito más que eso. ¿Es realmente malo el rendimiento de arrojar excepciones? ¿Hay puntos de referencia disponibles?


Realmente solo importa si su validación de datos está en un círculo cerrado. En la mayoría de los casos, no importa lo que elija, siempre y cuando sea coherente en su código.

Si tiene un montón de código que se parece a su ejemplo anterior, entonces puede querer limpiarlo mediante la introducción de un método auxiliar para lanzar ...

private void throwIf( bool condition, String message ) { if( condition ) throw new ApplicationException( message ); }

(también, hacer esto ayudará a concentrarse en errores como "validCheckOne = false" versus "validCheckOne == false" :)


Sugeriría que usar excepciones como se describe en la pregunta (para el control de flujo dentro de una función) es incorrecto, generalmente no es la mejor idea. Yo iría más lejos y diría que la validación arrojando excepciones no es el mejor enfoque; en su lugar, devuelve un booleano y almacena una lista de mensajes de error de validación a los que se puede acceder. Un método de guardar adjunto podría / debería arrojar una excepción si se invoca a un objeto no válido.

Por lo tanto, si la validación falla, los mensajes de error de validación se pueden mostrar al usuario (registrado, devuelto, lo que sea). Si la validación se aprueba, puede llamar a guardar. Si llama a guardar en un objeto no válido, obtenga una excepción apropiada.

Otro posible problema con su código de ejemplo (dependiendo de los requisitos, por supuesto) es que solo arroja el primer error de validación que ocurre. Imagine esto desde un POV de usuarios:

  • Clic en Guardar
  • Obtener un mensaje de error
  • Corregir error
  • Haga clic en guardar de nuevo
  • Obtener un mensaje de error diferente. Molesto.

Como usuario, prefiero obtener todos los errores de validación a la vez para poder corregirlos todos antes de volver a intentarlo.


Voy a repetir el mantra aquí: lanzar excepciones debe hacerse en circunstancias excepcionales. Los datos ingresados ​​no válidos realmente no son tan excepcionales.