Sigue sorprendiéndome que, en la actualidad, los productos que tienen años de uso en su haber, construidos por equipos de profesionales, aún hoy en día, no brindan mensajes de error útiles al usuario. En algunos casos, la adición de solo una pequeña información adicional podría ahorrarle al usuario horas de problemas.
Un programa que genera un error, lo generó por una razón. Tiene todo a su disposición para informar al usuario tanto como pueda, por qué algo falló. Y, sin embargo, parece que proporcionar información para ayudar al usuario es de baja prioridad. Creo que esto es un gran fracaso.
Un ejemplo es de SQL Server. Cuando intenta restaurar una base de datos que está en uso, con bastante razón no le permitirá. SQL Server sabe qué procesos y aplicaciones están accediendo a él. ¿Por qué no puede incluir información sobre los procesos que utilizan la base de datos? Sé que no todos pasan un Applicatio_Name
atributo en su cadena de conexión, pero incluso una pista sobre la máquina en cuestión podría ser útil.
Otro candidato, también SQL Server (y mySQL) es el encantador string or binary data would be truncated
mensaje de error y equivalentes. Muchas veces, una simple lectura de la declaración SQL que se generó y la tabla muestra qué columna es la culpable. Este no es siempre el caso, y si el motor de la base de datos detectó el error, ¿por qué no puede ahorrarnos ese tiempo y simplemente nos dice qué maldita columna era? En este ejemplo, podría argumentar que puede haber un impacto en el rendimiento al verificarlo y que esto impediría al escritor. Bien, lo compraré. ¿Qué tal si una vez que el motor de la base de datos sabe que hay un error, realiza una comparación rápida después del hecho, entre los valores que iban a almacenarse y las longitudes de las columnas? Luego, muéstralo al usuario.
Los horribles adaptadores de tabla de ASP.NET también son culpables. Las consultas se pueden ejecutar y se puede enviar un mensaje de error que indica que se está violando una restricción en alguna parte. Gracias por eso. Es hora de comparar mi modelo de datos con la base de datos, porque los desarrolladores son demasiado vagos para proporcionar incluso un número de fila o datos de ejemplo. (Para el registro, nunca usaría este método de acceso a datos por elección , ¡es solo un proyecto que heredé!).
Cada vez que lanzo una excepción de mi código C # o C ++, proporciono todo lo que tengo a mano para el usuario. Se tomó la decisión de tirarlo, de modo que cuanta más información pueda brindar, mejor. ¿Por qué mi función arrojó una excepción? ¿Qué se pasó y qué se esperaba? Me lleva un poco más de tiempo poner algo significativo en el cuerpo de un mensaje de excepción. Demonios, no hace más que ayudarme mientras me desarrollo, porque sé que mi código arroja cosas que son significativas.
Se podría argumentar que los mensajes de excepción complicados no deberían mostrarse al usuario. Si bien no estoy de acuerdo con eso, es un argumento que se puede apaciguar fácilmente al tener un nivel de verbosidad diferente dependiendo de su construcción. Incluso entonces, los usuarios de ASP.NET y SQL Server no son sus usuarios típicos, y preferirían algo lleno de verbosidad e información deliciosa porque pueden rastrear sus problemas más rápido.
¿Por qué los desarrolladores piensan que está bien, en estos tiempos, proporcionar la mínima cantidad de información cuando ocurre un error?
Es 2011 chicos, vienen en .
fuente
Respuestas:
Si bien hay muchos ejemplos de mensajes de error incorrectos que simplemente no deberían existir, debe tener en cuenta que no siempre es posible proporcionar la información que le gustaría ver.
También existe la preocupación de exponer demasiada información, lo que puede llevar a los desarrolladores a cometer errores por precaución. (Te prometo que el juego de palabras no fue intencionado, pero no lo eliminaré ahora que lo noté).
A veces, también existe el hecho de que un mensaje de error complejo es inútil para el usuario final. Ponerse del lado de la sobrecarga de información no es necesariamente un buen enfoque para los mensajes de error. (Eso puede ser mejor guardado para el registro).
fuente
For further information, see log20111701.txt
. Este sería un paso en la dirección correcta.Los desarrolladores no son las personas adecuadas para escribir mensajes de error.
Ven la aplicación desde el ángulo equivocado. Son extremadamente conscientes de lo que salió mal dentro del código, pero a menudo no se están acercando al software desde el punto de vista de intentar lograr algo. Como resultado, la información importante para el desarrollador no es necesariamente información importante para el usuario.
fuente
La vista caritativa:
El desarrollador trabajó de cerca con el código y luchó por comprender a alguien que no entendía cómo funcionaba. Como resultado, piensan que los mensajes de error están bien, simplemente no tienen un buen marco de referencia para juzgarlos.
Los mensajes de error inteligentes son realmente difíciles de hacer. No solo debe escribirlos, sino que debe resolver todo lo que pueda salir mal, evaluar la probabilidad y proporcionar información útil (que casi con certeza varía según el contexto) a la persona que lee el mensaje para que pueda corregirlo.
Para la mayoría de las aplicaciones, es difícil hacer un buen caso para el momento de hacer este tipo de cosas, así como al próximo desarrollador realmente le gustaría porque los errores no ocurren con tanta frecuencia. Además, si tuviera ese tiempo extra, ¿no debería pasarlo deteniendo los errores en lugar de informar sobre ellos?
La visión poco caritativa:
La realidad probablemente esté en algún punto intermedio, aunque mi experiencia en realidad me dice que es mucho más la primera que la última, básicamente es bastante difícil y requiere una gran cantidad de esfuerzo para lidiar con algo que probablemente no sucederá.
fuente
Process Handle Raped By Spawned Injector, Quitting SYstem.
... usuario: "wtf did I do?`). Pero en el caso de SQL Server / ASP.NET, creo que se podría haber hecho más esfuerzo :)string/binary data
error que extrae toda la información de la columna de dicha tabla, examina los valores anteriores y muestra qué columnas habrían estado en violación. Esto fue trivial. Tal vez me estoy quejando demasiado porque mis ejemplos de casos son triviales, pero entiendo totalmente que este no es siempre el caso. La forma en que detenemos los inyectores generados por los procesos de violación puede ser difícil :)Desafortunadamente, los mensajes de error más útiles le cuestan tiempo al desarrollador, lo que equivale al dinero de la empresa. Los productos son lo suficientemente caros como para construirlos. Sí, sería increíble tener mensajes de error más útiles, y estoy de acuerdo en que deberían incluirse otros más útiles. Sin embargo, es solo un hecho de la vida que cuando tienes una fecha límite y hay dinero en juego, tienes que cortar algo. Los "mensajes de error más bonitos", como los administradores pueden verlo, probablemente sean lo primero que se vaya.
fuente
Estoy de acuerdo en que los mensajes de error deben ser lo más específicos posible.
Una razón para los mensajes de error genéricos es probablemente el uso de códigos de error. Al usar excepciones, puede pasar todo lo que necesita en el mensaje de error. Usando códigos de retorno no hay espacio para codificar un nombre de columna. Quizás el error es manejado por una función genérica que no conoce el contexto y simplemente traduce el código de error a una cadena.
fuente
fuente
Como aviso general, debe considerar que cualquier error o situación excepcional es, exactamente eso: excepcional. Se cruza el procedimiento planificado y diseñado. Es incompatible con la forma en que las cosas se planearon para trabajar. Si este no fuera el caso, entonces no habría necesidad de rescatar con un error abortar.
Los programadores estamos capacitados para cuidar la autoprotección de este procedimiento planificado. Por lo tanto, incluimos rutinariamente algunos controles de cordura para verificar nuestros supuestos. Cuando estos controles de cordura fallan, sabemos que el plan de alguna manera falló ...
Su demanda, que puede parecer sentido común desde la perspectiva del usuario, es imposible de cumplir si considera la realidad de cómo funciona dicho sistema. Solicita una declaración ordenada con información bien organizada y adecuada añadida. Además, incluso pide que esta presentación se realice de una manera que se ajuste al diseño general de la aplicación / manejo. Obviamente esta información existe en algún lugar del sistema. Obviamente, incluso existe allí de manera ordenada y bien organizada (esperemos que sí). PERO en el momento en que ocurre el error, nadie planeó poner esta información a disposición. Un error siempre es una pérdida parcial de control.Esta pérdida de control puede ocurrir en varios niveles. Podría ser que el sistema se comporte en tiempo de ejecución de manera diferente a lo planeado. Pero también podría ser que la implementación real resultó mucho más difícil y diferente en los detalles que se planificaron, y no hubo una disposición presupuestaria para manejar esta situación satisfactoriamente. Esto también es una pérdida parcial de control.
Para relacionar esto con el ejemplo concreto que dio: Si, en el momento del error, se conociera el nombre y el tipo de la columna de la tabla, y además la longitud del espacio requerido, entonces no habría ninguna razón para planteando un error, ¿no? Podríamos solucionar la situación y proceder según lo planeado. El hecho de que nos veamos obligados a generar un error nos muestra que las cosas se extraviaron. El hecho mismo de que estas informaciones no estén disponibles es la excepción .
Lo que estoy escribiendo aquí puede parecer evidente y simple sentido común. Pero en realidad es extremadamente difícil de entender. Intentamos constantemente entenderlo aplicando categorías morales , como debe haber un culpable, debe haber una persona mala y perezosa que no se preocupe por el usuario pobre, debe haber un hombre de negocios codicioso que haya hecho un cálculo económico. Todo esto está completamente fuera del punto.
La posibilidad de pérdida de control se debe al hecho de que estamos haciendo las cosas de manera planificada y ordenada .
fuente
Trabajo como ingeniero de soporte para una empresa de software y, a menudo, vemos mensajes de error que son nuevos para nosotros. Con frecuencia, cuando remito estos a nuestro equipo de desarrollo, tienen que buscar el mensaje en la fuente de la aplicación.
Me parece que incluso si no se presentara a los usuarios, nos ahorraría mucho tiempo si el equipo de desarrollo agregara una nota a un documento o base de datos de índice de mensajes de error cada vez que agregaran uno nuevo, lo haría mucho más rápido para nosotros encontrar la causa de los problemas de los clientes y también ahorrarles tiempo ...
fuente
El problema que está viendo allí es en realidad uno de los efectos secundarios de la encapsulación adecuada y el ocultamiento de la información.
Los sistemas modernos son extremadamente complicados. Hay pocas posibilidades de que el desarrollador promedio pueda mantener, en su cabeza, un modelo mental de todo el sistema, desde la interfaz de usuario hasta el binario sin procesar, mientras codifica cualquier tarea en particular.
Entonces, mientras un desarrollador se sienta y codifica, digamos, el bit que restaura un archivo de base de datos, su modelo mental se llena por completo con los bits que rodean el acto de restaurar un archivo de base de datos. Necesita (y supongo que no he escrito este código) leer un archivo, verificar propiedades, leer versiones, hacer una copia de seguridad de los datos existentes, elegir una estrategia de fusión / sobrescritura, etc. Muy probablemente, incluso si hay un paso considerando la interfaz de usuario, está en la cadena de error que escribe en un controlador de excepciones. Algo como:
En este ejemplo, la información útil sobre la que está preguntando en términos de procesos que podrían estar usando el archivo, o incluso otros subprocesos en la base de datos, está completamente fuera de alcance (programáticamente). Puede haber cientos de clases que tratan con archivos DB; importar a esas clases información sobre cualquier otro proceso utilizando los archivos o la funcionalidad para acceder al sistema de archivos y observar los otros procesos en ejecución (suponiendo que esos procesos estén incluso en ESTA máquina) daría como resultado lo que se conoce como una abstracción con fugas ; Hay un costo directo en la productividad.
Así es como este tipo de errores pueden persistir en los días modernos. Obviamente, todos PODRÍAN ser reparados; pero en muchos casos, hay mucha más sobrecarga de lo que uno podría pensar (en este caso, por ejemplo, es posible que tenga que hacer que esta función atraviese la enumeración de conexiones de red y recursos compartidos para ver si una máquina remota está utilizando este archivo de base de datos para algunos razón) y el costo está lejos de ser trivial.
fuente
GenericException
, podría 1) Solicitar alProcesses
Subsistema una lista de procesos. 2) Pregunte a cada proceso qué base de datos están utilizando. 3) Haga coincidir el proceso con la base de datos asignada a la que estoy tratando de sobrescribir, 4) arroje unaDatabaseInUse(dbName, processName, applicationName
excepción. :)Mi favorito era (a finales de los años 70) el compilador Univac Fortran IV, cuando leía no dígitos, anunció fielmente
fuente
Creo que la mayoría de los mensajes de error son en realidad declaraciones de código de depuración / printf glorificadas (auto) orientadas al programador.
Escribir mensajes de error orientados al usuario significa saber quién es su usuario y anticipar lo que querrá saber. Mientras se encuentra en medio de la escritura del código, un desarrollador es más apto para escribir un mensaje de error útil para sí mismo, ya sea para depurar el código que está escribiendo en este momento, o útil para los casos de uso conocidos o predominantes.
Cambiar de escribir código a diseñar una parte textual de la interfaz de usuario (o experiencia del usuario) es un cambio de contexto. En aplicaciones grandes, como las aplicaciones multilingües que podrían significar que se entregan a una persona o equipo diferente (UI, traducción) en lugar de ser manejado completamente por el desarrollador, a menos que el desarrollador explique cuidadosamente el contexto del mensaje, se pueden obtener detalles importantes. Se pierde fácilmente.
Por supuesto, verificar y verificar el manejo de errores a menudo se considera de baja prioridad, siempre que se manejen los errores y excepciones (es decir, se detecten), no se le da mucho énfasis. Es un lugar mentalmente poco gratificante de la base de código para que lo evalúen los desarrolladores o el control de calidad, ya que las condiciones de error a menudo tienen una connotación negativa (es decir, error o falla) asociada a ellas.
fuente
Creo que la razón es que el informe / manejo de errores siempre se realiza como un pensamiento posterior . Incluso cuando no están completamente pensados, en su mayoría son ciudadanos de segunda clase en el diseño general.
El software moderno generalmente consta de múltiples capas. Cuando su lógica de informe de errores se establece rápidamente sin pensarlo demasiado, a menudo es difícil reunir toda la información necesaria para presentar mensajes de error útiles.
Por ejemplo, el error se detecta en el back-end, pero necesita cierta información de las capas superiores para componer un mensaje de error completo. La mayoría de los buenos mensajes de error necesitan información de casi todas las capas (para darnos una visión completa de lo que sucedió en el sistema). El mensaje de error ideal sería "OK, primero recibimos una cadena, luego pasó por el analizador que dio algo gracioso, es posible que desee mirar allí. De todos modos, la cosa se pasó más abajo ..."
Hacerlo a menudo requeriría un acoplamiento innecesario si el mecanismo de informe de errores no fuera ciudadano de primera clase durante la fase de diseño. Supongo que a la mayoría de la gente le parece demasiado trabajo para hacer algo que no parece impresionante (¿a quién le gusta decir "¿Ves? Mi programa se bloqueó y el mensaje de error es útil").
fuente