Imagina que estás creando un reproductor de video en JavaScript. Este reproductor de video repite el video del usuario repetidamente utilizando una función recursiva y, por eso, el navegador activará un too much recursion
RangeError
en algún momento.
Probablemente nadie usará tanto la función de bucle. Su aplicación nunca arrojará este error, ni siquiera si el usuario dejó la aplicación en bucle durante una semana, pero aún existe. Resolver el problema requerirá que rediseñe la forma en que funciona el bucle en su aplicación, lo que tomará una cantidad considerable de tiempo. ¿Qué haces? ¿Por qué?
Arreglar el error
Deja el error
¿No deberías arreglar solo los errores con los que la gente tropezará? ¿Cuándo la corrección de errores se vuelve excesiva, si alguna vez lo hace?
EDITAR:
Si el enfoque recursivo que no causa un error real es una preocupación para usted, suponga que por cada vez que el reproductor reproduce un video, aumenta una variable 1
. Después de 2 53 bucles, esta variable se desbordará y su programa no podrá manejarla, lanzando una excepción.
fuente
Respuestas:
Tienes que ser pragmático.
Si es poco probable que el error se active en el mundo real y el costo de la reparación es alto, dudo que muchas personas lo consideren un buen uso de los recursos para solucionarlo. Sobre esa base, diría que lo deje, pero asegúrese de que el pirateo esté documentado para usted o su sucesor en unos meses (consulte el último párrafo).
Dicho esto, debe usar este problema como una "experiencia de aprendizaje" y la próxima vez que realice un bucle no use un bucle recursivo innecesariamente.
Además, prepárate para ese informe de error. Se sorprenderá de lo buenos que son los usuarios finales para superar los límites y descubrir defectos. Si se convierte en un problema para los usuarios finales, tendrá que solucionarlo, entonces se alegrará de haber documentado el hack.
fuente
Hubo un error similar en Windows 95 que hizo que las computadoras se bloqueen después de 49.7 días . Solo se notó algunos años después del lanzamiento, ya que muy pocos sistemas Win95 se mantuvieron así de todos modos. Entonces, hay un punto: los errores pueden volverse irrelevantes por otros errores más importantes.
Lo que debe hacer es una evaluación de riesgos para el programa en su conjunto y una evaluación de impacto para errores individuales.
Y así. Esto afecta la clasificación de errores , el proceso de decidir qué errores corregir. Casi todo el software de envío tiene listas muy largas de errores menores que aún no se han considerado lo suficientemente importantes como para solucionarlos.
fuente
Las otras respuestas ya son muy buenas, y sé que su ejemplo es solo un ejemplo, pero quiero señalar una gran parte de este proceso que aún no se ha discutido:
Debe identificar sus suposiciones y luego probar esas suposiciones contra los casos de esquina.
Mirando tu ejemplo, veo un par de suposiciones:
Otras personas han discutido la primera suposición, pero miren la segunda suposición: ¿qué pasa si mi video es solo una fracción de segundo?
Y claro, tal vez ese no sea un caso de uso muy común. ¿Pero estás realmente seguro de que nadie subirá un video muy corto? Estás asumiendo que los videos tienen una duración mínima, ¡y probablemente ni siquiera te diste cuenta de que estabas asumiendo algo! ¿Podría esta suposición causar otros errores en otros lugares de su aplicación?
Los supuestos no identificados son una gran fuente de errores.
Como dije, sé que su ejemplo es solo un ejemplo, pero este proceso de identificar sus suposiciones (que a menudo es más difícil de lo que parece) y luego pensar en excepciones a esas suposiciones es un factor muy importante para decidir dónde pasar su tiempo.
Entonces, si te encuentras pensando "No debería tener que programar alrededor de esto, ya que nunca sucederá", entonces deberías tomarte un tiempo para examinar realmente esa suposición. A menudo pensará en casos de esquina que podrían ser más comunes de lo que pensaba originalmente.
Dicho esto, hay un punto en el que esto se convierte en un ejercicio inútil. Probablemente no le importe si su aplicación de JavaScript funciona perfectamente en una calculadora TI-89, por lo que gastar cualquier cantidad de tiempo en eso simplemente se desperdicia.
Las otras respuestas ya han cubierto esto, pero llegar a esa línea entre "esto es importante" y "esto es una pérdida de tiempo" no es una ciencia exacta, y depende de muchos factores que pueden ser completamente diferentes de uno persona o empresa a otra.
Pero una gran parte de ese proceso es primero identificar sus supuestos y luego tratar de reconocer las excepciones a esos supuestos.
fuente
What's the worst thing that could happen?
Le recomendaría que lea el siguiente documento:
La confiabilidad y sus amenazas: una taxonomía
Entre otras cosas, describe varios tipos de fallas que pueden ocurrir en su programa. Lo que describió se llama falla latente , y en este documento se describe así:
Habiendo descrito esto, todo se reduce a una relación costo-beneficio. El costo consistiría en tres parámetros:
Los dos primeros son cruciales. Si se trata de un error que se manifestaría una vez en una luna azul y / o a nadie le importa, o tiene una solución perfectamente buena y práctica, entonces puede documentarlo con seguridad como un problema conocido y pasar a un desafío más y más tareas importantes Sin embargo, si el error ocasiona que algunas transacciones de dinero fallen, o interrumpa un proceso de registro largo, frustrando así al usuario final, entonces debe actuar en consecuencia. El tercer parámetro es algo que desaconsejo encarecidamente. En palabras de Vito Corleone:
Si eres un profesional, deja de lado las emociones y actúa de manera óptima. Sin embargo, si la aplicación que está escribiendo es un pasatiempo suyo, entonces está involucrado emocionalmente, y el tercer parámetro es tan válido como cualquiera en términos de decidir si corregir un error o no.
fuente
Ese error solo permanece sin descubrir hasta el día en que alguien coloca a su jugador en la pantalla del lobby ejecutando una presentación de la compañía 24/7. Entonces sigue siendo un error.
La respuesta a ¿Qué haces? es realmente una decisión comercial, no de ingeniería:
fuente
Especialmente en grandes empresas (o grandes proyectos) hay una forma muy pragmática de establecer qué hacer.
Si el costo de la reparación es mayor que el retorno que traerá la solución, entonces mantenga el error. A la inversa, si la solución devolverá más de su costo, solucione el error.
En su escenario de muestra, depende de la cantidad de usuarios que espera perder frente a la cantidad de usuarios que obtendrá si desarrolla nuevas funciones en lugar de corregir ese costoso error.
fuente
TL; DR Esto es por qué
RESOLVED/WONTFIX
es una cosa. Simplemente no lo use en exceso: la deuda técnica puede acumularse si no tiene cuidado. ¿Es este un problema fundamental con su diseño, que probablemente cause otros problemas en el futuro? Entonces arréglalo. ¿De otra manera? Déjelo hasta que se convierta en una prioridad (si alguna vez lo hace).fuente
En realidad, hay tres errores en la situación que describe:
La falta de un proceso para evaluar todos los errores registrados (usted registró el error en su ticket / trabajo atrasado / cualquier sistema que tenga instalado, ¿verdad?) Para determinar si se debe corregir o no. Esta es una decisión de gestión.
La falta de habilidades en su equipo que lleva al uso de soluciones defectuosas como esta. Es urgente abordar esto para evitar futuros problemas. (Comience a aprender de sus errores).
El problema de que el video puede dejar de mostrarse después de mucho tiempo.
De los tres errores, solo (3) podrían no necesitar ser reparados.
fuente
Aquí hay muchas respuestas que analizan la evaluación del costo de la corrección del error en lugar de dejarlo. Todos contienen buenos consejos, pero me gustaría agregar que el costo de un error a menudo se subestima, posiblemente se subestima enormemente. La razón es que los errores existentes confunden las aguas para un desarrollo y mantenimiento continuos. Hacer que sus evaluadores realicen un seguimiento de varios errores "no solucionarán" mientras navega por su software tratando de encontrar nuevos errores hace que su trabajo sea más lento y más propenso a errores. Unos pocos errores "no solucionarán" que es poco probable que afecten a los usuarios finales aún harán más lento el desarrollo continuo y el resultado será más problemático.
fuente
Una cosa que aprendí en mis años de codificación es que volverá un error. El usuario final siempre lo descubrirá e informará. Si va a corregir el error o no es "meramente" una cuestión de prioridad y fecha límite.
Hemos tenido errores importantes (en mi opinión, importantes) que se decidieron no corregir en una versión, solo para convertirse en un obstáculo para la próxima versión porque el usuario final tropezó con ella una y otra vez. Lo mismo a la inversa: nos presionaron para corregir un error en una función que nadie usa, pero fue útil para la administración.
fuente
Aquí hay tres cosas:
Principios
Esta es una cara de la moneda. Hasta cierto punto, creo que es bueno insistir en corregir errores (o malas implementaciones, incluso si "funcionan"), incluso si nadie se da cuenta.
Míralo de esta manera: el problema real no es necesariamente el error, en tu ejemplo, sino el hecho de que un programador pensó que era una buena idea implementar el bucle de esta manera, en primer lugar. Era obvio desde el primer momento, que esta no era una buena solución. Ahora hay dos posibilidades:
El programador simplemente no se dio cuenta. Bueno ... un programador debe desarrollar una intuición de cómo se ejecuta su código. No es que la recursión sea un concepto muy difícil. Al corregir el error (y sudar a través de todo el trabajo adicional), tal vez aprenda algo y lo recuerde, aunque solo sea para evitar el trabajo adicional en el futuro. Si la razón era que él no tenía el tiempo suficiente, la gestión podría aprender que los programadores no necesitan más tiempo para crear un código de mayor calidad.
El programador lo notó, pero lo consideró "no es un problema". Si esto se deja en pie, entonces se desarrolla una cultura de laissez-faire que, en última instancia, conducirá a errores donde realmente duele. En este caso particular, a quién le importa. Pero, ¿qué pasa si ese programador está desarrollando una aplicación bancaria la próxima vez y decide que cierta constelación nunca sucederá? Entonces lo hace. Malos tiempos.
Pragmatismo
Este es el otro lado. Por supuesto, es probable que, en este caso particular, no solucione el error. Pero cuidado: hay pragmatismo y luego hay pragmatismo. Un buen pragmatismo es si encuentra una solución rápida pero sólida pero bien fundada para un problema. Es decir, evitas diseñar cosas en exceso, pero las cosas que implementas todavía están bien pensadas. El pragmatismo malo es cuando simplemente piratea algo que funciona "exactamente" y se romperá en la primera oportunidad.
Falla rápido, falla duro
En caso de duda, falle rápido y fracase duro.
Esto significa, entre otros, que su código nota la condición de error, no el entorno.
En este ejemplo, lo menos que puede hacer es hacerlo para que no ocurra el error de tiempo de ejecución difícil ("profundidad de pila excedida" o algo así), reemplazándolo por una fuerte excepción propia. Podría, por ejemplo, tener un contador global y decidir arbitrariamente que rescatará después de 1000 videos (o cualquier número que sea lo suficientemente alto como para que nunca ocurra en el uso normal, y lo suficientemente bajo como para funcionar en la mayoría de los navegadores). Luego, dale a esa excepción (que puede ser una excepción genérica, por ejemplo, una
RuntimeException
en Java o una cadena simple en JavaScript o Ruby) un mensaje significativo. No tiene que ir al extremo para crear un nuevo tipo de excepciones o lo que sea que haga en su lenguaje de programación particular.De esta manera, tienes
Mi convención es prefijar tales mensajes de error con la palabra "Paranoia:". Esta es una señal clara para mí y para todos los demás de que nunca espero que se produzca ese error. Puedo separarlos claramente de las excepciones "reales". Si veo uno así en una GUI o un archivo de registro, sé con certeza que tengo un problema grave: después de todo, nunca esperé que ocurrieran. En este punto, entro en modo crujiente (con una buena posibilidad de resolverlo rápida y fácilmente, ya que sé exactamente dónde ocurrió el problema, salvándome de muchas depuraciones espurias).
fuente
Un post-it en el escritorio de un desarrollador senior en mi lugar de trabajo dice
Creo que a menudo es un buen punto de partida para el proceso de pensamiento. Siempre hay muchas cosas que arreglar y mejorar, pero ¿cuánto valor estás agregando realmente? ... ya sea en usabilidad, confiabilidad, mantenibilidad, legibilidad, rendimiento ... o cualquier otro aspecto.
fuente
Se me ocurren tres cosas:
Primero , el impacto de un error identificado debe investigarse a fondo antes de que la decisión de dejar el error en el código se pueda tomar de manera responsable. (En el ejemplo que a la vez pensé en la pérdida de memoria de la pila cada vez mayor y representa lo que podría hacer que su navegador más lento y más lento con cada recursividad.) Esta exhaustiva investigación a menudo lleva más tiempo que iba a corregir el error, por lo que preferiría fijación El error en la mayoría de los casos.
En segundo lugar , los errores tienden a tener más impacto de lo que uno piensa al principio. Todos estamos muy familiarizados con el código de trabajo porque este es el caso "normal". Los errores, por otro lado, son una "excepción". Por supuesto, todos hemos visto muchos errores, pero hemos visto mucho más código de trabajo en general. Por lo tanto, tenemos más experiencia con el comportamiento del código de trabajo que con el comportamiento del código defectuoso. Hay miles de millones de libros sobre el código de trabajo y lo que hará en qué situaciones. Hay casi nada sobre el comportamiento del código con errores.
La razón de esto es simple: los errores no son orden sino caos . A menudo les queda un rastro de orden (o al revés: no destruyen el orden por completo), pero su naturaleza defectuosa es una destrucción del orden que el programador quería. El propio caos tiende a desafiar la estimación correcta. Es mucho más difícil decir qué hará un programa con un error que lo que hará un programa correcto solo porque ya no se ajusta a nuestros patrones mentales.
Tercero , su ejemplo contenía el aspecto de que corregir el error significaría tener que rediseñar el programa. (Si elimina este aspecto, la respuesta es simple: corrija el error, no debería tomar demasiado tiempo porque no es necesario rediseñarlo. De lo contrario :) En tal caso, perdería la confianza en el programa tal como está diseñado actualmente. El rediseño sería una forma de restaurar esa confianza.
Dicho todo esto , los programas son cosas que la gente usa, y una característica faltante o un segundo error realmente engorroso en otros lugares puede tener prioridad sobre la corrección de su error. Por supuesto, luego tome el camino pragmático y haga otras cosas primero. Pero nunca olvide que una primera estimación rápida del impacto de un error puede ser completamente errónea.
fuente
Probabilidad baja / consecuencias leves = arreglo de baja prioridad
Pero esto no puede convertirse en una muleta para los desarrolladores perezosos ...
Para establecer que la probabilidad de ocurrencia es muy baja y las consecuencias son leves, el equipo de desarrollo debe comprender el código, los patrones de uso y la seguridad.
La mayoría de los desarrolladores se sorprenden de que las cosas que pensaban originalmente nunca sucederán, en realidad suceden mucho
Nuestro sistema educativo no enseña muy bien la probabilidad y la lógica. La mayoría de las personas, incluida la mayoría de los ingenieros de software, tienen una lógica y una intuición de proabilidad rotas. La experiencia con problemas del mundo real y la experiencia con simulaciones extensas son la única forma en que sé solucionar esto.
Enfrenta tu intuición con datos del mundo real
Es importante hacer varios registros para poder seguir los patrones de uso. Rellene el código con afirmaciones de cosas que cree que no deberían suceder. Te sorprenderá que lo hagan. De esa manera podrá confrontar su intuición con datos duros y refinarlos.
Mi ejemplo de un problema leve y una medida de control
En un sitio de comercio electrónico en el que trabajé hace mucho tiempo, otro programador cometió un error: en una condición oscura, el sistema le cobraba al cliente un centavo menos de lo registrado en los registros. Descubrí el error porque hice informes para identificar las diferencias entre los registros y los saldos de cuentas para hacer que el sistema contable sea más resistente. Nunca solucioné este error porque la diferencia era muy pequeña. La diferencia se calculó diariamente y fue inferior a US $ 2,00 mensuales. Ocurre que estábamos desarrollando un sistema completamente nuevo que en un año debería reemplazar al actual. No tiene sentido desviar recursos de proyectos potencialmente rentables para arreglar algo que cuesta US $ 2.00 mensuales y fue sometido a una medida de control apropiada.
Conclusión
Sí, hay errores que no necesitan ser reparados de inmediato, que no son lo suficientemente importantes como para retrasar el desarrollo de nuevas funciones. Sin embargo, el sistema debe tener el control de la aparición de este error para asegurarse de que sea pequeño porque no podemos confiar en nuestra propia intuición.
fuente
Creo que esto es una pregunta equivocada desde el principio.
La pregunta no es "¿debería solucionar este error o no debería solucionarlo?". Cualquier desarrollador tiene una cantidad de tiempo limitada. Entonces la pregunta es "¿qué es lo más útil que puedo hacer en una hora, cuatro horas o una semana"?
Si corregir el error es lo más útil, ya que mejora el software en la mayor cantidad posible para la mayoría de las personas, entonces corríjalo. Si puede realizar mejoras más importantes en otros lugares, agregando características que faltan personas o solucionando un error más importante, haga estas otras cosas. Y puntos de bonificación adicionales por cualquier cosa que haga que su desarrollo futuro sea más eficiente.
fuente
La corrección de errores siempre es una exageración
Vamos a clasificar insecto primera parte.
¿Es un error honesto , por ejemplo, un error único o una sombra variable que escapó de las pruebas? En este caso, espero que, además de "solucionar" el problema, también escribiste nuevas pruebas unitarias, aproveché la oportunidad para refactorizar el código cercano, donde todo lo último es un trabajo útil .
Sin embargo, si en realidad es una falla de diseño como lo es en su caso, debe reevaluar el diseño o, en el peor de los casos, deshabilitar esta función.
Entonces, por favor no intentes arreglarlo .
Podría hacerlo peor, por supuesto, podría probar la metodología de hack-on-hack . El bucle de video es un truco (mala arquitectura y se conoce una rotura). Puede agregar un límite de bucle , de modo que después de N iteraciones (que ha probado está por debajo del límite del navegador) el bucle termina.
Las ramificaciones son obvias, ahora debe admitir tanto el código roto como el nuevo límite de bucle.
PD disculpas por la visión extrema.
PPS Una nota sobre terminología: no se puede "arreglar" un error. Bueno, quizás un veterinario podría, pero no vayamos allí ;-). Los problemas se resuelven o "arreglan", mientras que los errores se eliminan o se solucionan.
fuente