Al diseñar excepciones, ¿debo escribir mensajes que un usuario o un desarrollador deben entender? ¿Quién debería ser el lector de mensajes de excepción?
Creo que los mensajes de excepción no son útiles en absoluto y siempre me cuesta escribirlos. Por convención, el tipo de excepción ya debería decirnos por qué algo no funcionó y las propiedades personalizadas podrían agregar aún más información, como nombres de archivos, índices, claves, etc. ¿Entonces por qué repetirlo en el mensaje mismo? Un mensaje autogenerado también podría funcionar y todo lo que tenía que contener es el nombre de la excepción con una lista de propiedades adicionales. Esto sería exactamente tan útil como un texto escrito a mano.
¿No sería mejor no escribir mensajes, sino tener procesadores de excepciones especiales que se encarguen de crear mensajes significativos tal vez en diferentes idiomas en lugar de codificarlos en código?
Me preguntaron si alguna de esas preguntas proporciona una respuesta a mi pregunta:
- Cómo escribir un buen mensaje de excepción
- ¿Por qué muchos mensajes de excepción no contienen detalles útiles?
Los he leído a ambos y no estaba contento con sus respuestas. Hablan de los usuarios en general y se centran en el contenido del mensaje en sí, en lugar del destinatario, y resulta que puede haber al menos dos de ellos: el usuario final y el desarrollador. Nunca sé con quién debo hablar al escribir mensajes de excepción.
Incluso creo que el famoso mensaje no tiene ningún valor real, ya que solo repite el nombre del tipo de excepción en diferentes palabras, así que ¿por qué molestarse en escribirlos? Puedo generarlos perfectamente automáticamente.
Para mí, el mensaje de excepción carece de una diferenciación de sus lectores. Una excepción perfecta debería proporcionar al menos dos versiones del mensaje: una para el usuario final y otra para el desarrollador. Llamarlo solo un mensaje es demasiado genérico. Un mensaje del desarrollador debe escribirse en inglés, pero el mensaje del usuario final puede necesitar ser traducido a otros idiomas. No es posible lograr todo esto con un solo mensaje, por lo que una excepción necesitaría proporcionar algún identificador al mensaje del usuario final que, como acabo de decir, podría estar disponible en diferentes idiomas.
Cuando leo todas las otras preguntas vinculadas, tengo la impresión de que un mensaje de excepción está destinado a ser leído por un usuario final y no por un desarrollador ... un solo mensaje es como tener un pastel y comérselo también.
fuente
Respuestas:
Esos mensajes son para otros desarrolladores.
Se espera que los desarrolladores lean esos mensajes para ayudarlos a depurar la aplicación. Esto puede tomar dos formas:
Depuración activa En realidad, está ejecutando un depurador mientras escribe código e intenta averiguar qué sucede. En este contexto, una excepción útil lo guiará al facilitarle la comprensión de lo que está sucediendo o, eventualmente, le sugerirá una solución alternativa (aunque esto es opcional).
Depuración pasiva. El código se ejecuta en producción y falla. La excepción se registra, pero solo obtiene el mensaje y el seguimiento de la pila. En este contexto, un mensaje de excepción útil lo ayudará a localizar rápidamente el error.
Dado que esos mensajes a menudo se registran, también significa que no debe incluir información confidencial allí (como claves privadas o contraseñas, incluso si pudiera ser útil para depurar la aplicación).
Por ejemplo, el
IOSecurityException
tipo de excepción que se produce al escribir un archivo no es muy explícito sobre el problema: ¿es porque no tenemos permisos para acceder a un archivo? ¿O tal vez podamos leerlo, pero no escribir? ¿O tal vez el archivo no existe y no tenemos permisos para crear archivos allí? O tal vez está bloqueado (con suerte, el tipo de excepción será diferente en este caso, pero en la práctica, los tipos a veces pueden ser crípticos). ¿O tal vez Code Access Security nos impide realizar cualquier operación de E / S?En lugar:
Es mucho más explícito. Aquí, sabemos de inmediato que los permisos en el directorio están configurados correctamente (de lo contrario, no podremos saber que el archivo existe), pero los permisos a nivel de archivo son problemáticos.
Esto también significa que si no puede proporcionar ninguna información adicional que no esté en el tipo de excepción, puede mantener el mensaje vacío.
DivisionByZeroException
Es un buen ejemplo donde el mensaje es redundante. Por otro lado, el hecho de que la mayoría de los idiomas le permiten lanzar una excepción sin especificar su mensaje se hace por una razón diferente: ya sea porque el mensaje predeterminado ya está disponible o porque se generará más tarde si es necesario (y la generación de este mensaje). el mensaje está encerrado dentro del tipo de excepción, lo que tiene mucho sentido, "OOPly" hablando).Tenga en cuenta que por razones técnicas (a menudo de rendimiento), algunos mensajes terminan siendo mucho más crípticos de lo que deberían ser. .NET's
NullReferenceException
:es un excelente ejemplo de un mensaje que no es útil. Un mensaje útil sería:
¡Esos mensajes no son para usuarios finales!
No se espera que los usuarios finales vean mensajes de excepción. Nunca. Aunque algunos desarrolladores terminan mostrando esos mensajes a los usuarios, esto conduce a una experiencia de usuario deficiente y a la frustración. Mensajes como:
no significa absolutamente nada para un usuario final y debe evitarse a toda costa.
El peor de los casos es tener un try / catch global que arroje la excepción al usuario y salga de la aplicación. Una aplicación que se preocupa por sus usuarios:
Maneja excepciones en primer lugar. La mayoría se pueden manejar sin molestar al usuario. ¿La red está inactiva? ¿Por qué no esperar unos segundos y volver a intentarlo?
Impide que un usuario dirija la aplicación a un caso excepcional. Si le pide al usuario que ingrese dos números y divida el primero por el segundo, ¿por qué permitiría al usuario ingresar cero en el segundo caso para culparlo unos segundos después? ¿Qué hay de resaltar el cuadro de texto en rojo (con una información útil que dice que el número debe ser diferente a cero) y deshabilitar el botón de validación hasta que el campo permanezca rojo?
Invita a un usuario a realizar una acción en un formulario que no sea un error. ¿No hay suficientes permisos para acceder a un archivo? ¿Por qué no pedirle al usuario que otorgue permisos administrativos o elegir un archivo diferente?
Si nada más funciona, muestra un error útil y amigable que está escrito específicamente para reducir la frustración del usuario, ayudarlo a comprender qué salió mal y eventualmente resolver el problema, y también ayudarlo a prevenir el error en el futuro (cuando corresponda).
En su pregunta, sugirió tener dos mensajes en una excepción: uno técnico para desarrolladores y otro para usuarios finales. Si bien esta es una sugerencia válida en algunos casos menores, la mayoría de las excepciones se producen a un nivel en el que es imposible producir un mensaje significativo para los usuarios. Tome
DivisionByZeroException
e imagine que no podríamos evitar que ocurra la excepción y no podemos manejarla nosotros mismos. Cuando ocurre la división, ¿sabe el marco (ya que es el marco, y no el código comercial, lo que arroja la excepción) cuál será un mensaje útil para un usuario? Absolutamente no:En cambio, uno puede dejar que arroje la excepción, y luego atraparlo en un nivel superior donde conocemos el contexto comercial y podríamos actuar en consecuencia para ayudar realmente al usuario final, mostrando así algo como:
o tal vez:
Esos mensajes no son para analizar
Tampoco se espera que los mensajes de excepción sean analizados o utilizados mediante programación. Si cree que la persona que llama puede necesitar información adicional, inclúyala en la excepción junto con el mensaje. Esto es importante porque el mensaje está sujeto a cambios sin previo aviso. El tipo es parte de la interfaz, pero el mensaje no lo es: nunca confíe en él para el manejo de excepciones.
Imagine el mensaje de excepción:
Desea extraer los valores "500", "6", "4" y "377". Piensa un poco en el enfoque que usarás para hacer el análisis, y solo entonces continúa leyendo.
Tienes la idea? Excelente.
Ahora, el desarrollador original descubrió un error tipográfico:
debiera ser:
Además, el desarrollador considera que mes / semana / una hora no son particularmente relevantes, por lo que también realiza un cambio adicional:
¿Qué pasa con tu análisis?
En lugar de analizar, podría estar utilizando propiedades de excepción (que pueden contener lo que uno quiera, tan pronto como se puedan serializar los datos):
¿Qué tan fácil es usar estos datos ahora?
A veces (como en .NET), el mensaje puede incluso traducirse al idioma del usuario (en mi humilde opinión, traducir esos mensajes es absolutamente incorrecto, ya que se espera que cualquier desarrollador pueda leer en inglés). Analizar tales mensajes es casi imposible.
fuente
La respuesta a esto depende completamente de la excepción.
La pregunta más importante es "¿quién puede solucionar el problema?" Si la excepción es causada por un error del sistema de archivos mientras está abriendo un archivo, puede tener sentido dar ese mensaje al usuario final. El mensaje puede contener más información sobre cómo solucionar el error. Puedo pensar en un caso definitivo en mi trabajo en el que tenía un sistema de complementos que cargaba archivos DLL. Si un usuario cometió un error tipográfico en la línea de comando para cargar el complemento incorrecto, el mensaje de error del sistema subyacente en realidad contenía información útil para permitirle corregir el problema.
Sin embargo, la mayoría de las veces, el usuario no puede solucionar una excepción no detectada. La mayoría de ellos implica hacer cambios en el código. En estos casos, el consumidor del mensaje es claramente un desarrollador.
El caso de las excepciones detectadas es más complicado porque tiene la oportunidad de procesar adecuadamente la excepción y lanzar una más amigable. Un lenguaje de scripting que escribí arrojó excepciones cuyo mensaje estaba claramente destinado a un desarrollador. Sin embargo, a medida que la pila se desenrollaba, agregué rastros de pila legibles por el usuario desde el lenguaje de scripting. Mis usuarios rara vez podían asimilar el mensaje, pero podían ver el rastro de la pila en su secuencia de comandos y averiguar qué sucedía el 95% del tiempo. Para el 5% restante, cuando me llamaron, no solo teníamos un seguimiento de la pila, sino un mensaje preparado por el desarrollador para ayudarme a descubrir qué estaba mal.
En general, trato el mensaje de excepción como un contenido desconocido. Alguien más arriba, que sabía más sobre las implementaciones, le ha dado a mi software una excepción. A veces tengo el presentimiento de que el contenido desconocido será útil para un usuario final, a veces no.
fuente