¿Cuándo la corrección de errores se vuelve excesiva, si es que alguna vez?

128

Imagina que estás creando un reproductor de video en JavaScript. Este reproductor de video reproduce el video del usuario repetidamente usando una función recursiva y, debido a 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 lanzará este error, ni siquiera si el usuario dejó el bucle de la aplicación 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 llevará una cantidad de tiempo considerable. ¿Qué haces? ¿Por qué?

  • Corrija el error

  • Deja el error

¿No deberías solo arreglar los errores en los que la gente tropezará? ¿Cuándo las correcciones de errores se vuelven excesivas, si alguna vez lo hacen?

EDIT:

Si el enfoque recursivo que no causa un error real es una preocupación para usted, suponga que por cada vez que el reproductor reproduzca un video, una variable aumenta en 1 . Después de 2 bucles 53 , esta variable se desbordará y su programa no podrá manejarla, lanzando una excepción.

    
pregunta Tiago Marinho 17.10.2016 - 07:16
fuente

16 respuestas

164

Tienes que ser pragmático.

Si es poco probable que el error se desencadene en el mundo real y el costo de reparación es alto, dudo que muchas personas lo consideren un buen uso de los recursos para corregir. Sobre esa base, diría que déjelo, pero asegúrese de que el hackeo esté documentado para usted o su sucesor en unos meses (consulte el último párrafo).

Dicho esto, debes usar este problema como una "experiencia de aprendizaje" y la próxima vez que hagas un ciclo no uses un ciclo recursivo innecesariamente.

También, prepárate para ese informe de error. Usted 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 pirateo.

    
respondido por el mcottle 17.10.2016 - 07:36
fuente
80

Hubo un error similar en Windows 95 que causó que se bloqueen después de 49.7 días . Solo se notó algunos años después del lanzamiento, ya que de todos modos muy pocos sistemas Win95 se mantuvieron al tanto. Así que hay un punto: los errores pueden ser irrelevantes por otros errores más importantes.

Lo que tienes que hacer es una evaluación de riesgos para el programa en su conjunto y una evaluación de impacto para errores individuales.

  • ¿Este software está en un límite de seguridad?
  • Si es así, ¿puede este error resultar en una vulnerabilidad?
  • ¿Es este software "crítico para la misión" para sus usuarios previstos? (Consulte la lista de cosas que el EULA de Java le prohíbe usarlo para )
  • ¿El error puede provocar la pérdida de datos? ¿Perdidas financieras? Pérdida de reputación?
  • ¿Qué tan probable es que ocurra este error? (Has incluido esto en tu escenario)

Y así sucesivamente. Esto afecta al error triage , 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 corregirlos.

    
respondido por el pjc50 17.10.2016 - 17:40
fuente
33

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 en casos de esquina.

Mirando tu ejemplo, veo un par de suposiciones:

  • El enfoque recursivo eventualmente causará un error.
  • Nadie verá este error porque los videos tardan demasiado en reproducirse para alcanzar el límite de la pila.

Otras personas han discutido la primera suposición, pero mira la segunda: ¿qué pasa si mi video solo dura una fracción de segundo?

Y seguro, tal vez no sea un caso de uso muy común. ¿Pero estás realmente seguro de que nadie cargará un video muy corto? ¡Está asumiendo que los videos tienen una duración mínima, y probablemente ni siquiera se dio cuenta de que estaba asumiendo algo! ¿Podría esta suposición causar otros errores en otros lugares de su aplicación?

Las suposiciones no identificadas 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 gastar tu tiempo.

Entonces, si te encuentras pensando: "No debería tener que programar 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 originalmente pensó.

Dicho esto, hay un punto en el que esto se convierte en un ejercicio de futilidad. Probablemente no te importe si tu aplicación de JavaScript funciona perfectamente en una calculadora TI-89, por lo que gastar cualquier cantidad de tiempo en eso solo se desperdicia.

Las otras respuestas ya cubrieron esto, pero encontrar 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 una persona o empresa a otra.

Pero una gran parte de ese proceso es primero identificar sus suposiciones y luego tratar de reconocer las excepciones a esas suposiciones.

    
respondido por el Kevin Workman 17.10.2016 - 17:32
fuente
13

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 una falla latente , y en este documento se describe así:

  

Un error está activo cuando produce un error, de lo contrario está inactivo. Un   el fallo activo es a) un fallo interno que antes estaba inactivo y   que ha sido activado por el proceso de cómputo o ambiental.   condiciones, o b) un fallo externo. La activación de fallos es la aplicación de   una entrada (el patrón de activación) a un componente que causa una inactividad   culpa de ser activo. La mayoría de las fallas internas circulan entre sus latentes.   y estados activos

Habiendo descrito esto, todo se reduce a una relación costo-beneficio. El costo consistiría en tres parámetros:

  • ¿Con qué frecuencia se presentaría el problema?
  • ¿Cuáles serían las consecuencias?
  • ¿Cuánto te molesta personalmente?

Los dos primeros son cruciales. Si es un error que se manifestaría una vez en una luna azul y / o nadie se preocupa por él, o si tiene una solución perfectamente buena y práctica, entonces puede documentarlo de forma segura como un problema conocido y pasar a otro más desafiante y más Tareas importantes. Sin embargo, si el error causaría que fallara alguna transacción de dinero, o interrumpiera un largo proceso de registro, frustrando así al usuario final, entonces tiene que actuar en consecuencia. El tercer parámetro es algo que recomiendo encarecidamente. En palabras de Vito Corleone:

  

No es personal. Es un negocio.

Si eres un profesional, deja las emociones a un lado y actúa de manera óptima. Sin embargo, si la aplicación que estás escribiendo es un pasatiempo tuyo, entonces estás involucrado emocionalmente, y el tercer parámetro es tan válido como cualquier otro para decidir si corregir un error o no.

    
respondido por el Vladimir Stokic 17.10.2016 - 09:10
fuente
12

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. Así que sigue siendo un error.

La respuesta a ¿Qué haces? es realmente una decisión de negocios, no de ingeniería:

  • Si el error solo afecta al 1% de sus usuarios, y su reproductor carece de soporte para una función requerida por otro 20%, la elección es obvia. Documente el error y luego continúe.
  • Si la corrección de errores está en su lista de tareas pendientes, a menudo es mejor corregirla antes de comenzar a agregar nuevas funciones. Obtendrá los beneficios del proceso de desarrollo de software sin defectos, y no perderá mucho tiempo ya que está en su lista de todos modos.
respondido por el Dmitry Grigoryev 17.10.2016 - 16:34
fuente
5

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 rendimiento que traerá la solución, entonces mantenga el error. Viceversa si la solución devolverá más que su costo, entonces arregle el error.

En su escenario de muestra, depende de la cantidad de usuarios que espera perder y la cantidad de usuarios que ganará si desarrolla nuevas funciones en lugar de corregir ese costoso error.

    
respondido por el JoulinRouge 17.10.2016 - 13:58
fuente
5

tl; dr Esta es la razón por la cual 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éjalo ser hasta que se convierta en una prioridad (si alguna vez lo hace).

    
respondido por el Lightness Races in Orbit 17.10.2016 - 18:26
fuente
5

En realidad, hay tres errores en la situación que describe:

  1. La falta de un proceso para evaluar todos los errores registrados (usted anotó el error en su ticket / backlog / cualquier sistema que tenga instalado, ¿no?) para determinar si debería repararse o no. Esta es una decisión de la gerencia.

  2. La falta de habilidades en su equipo que lleva al uso de soluciones defectuosas como esta. Esto es urgente para hacer frente a esto para evitar problemas futuros. (Comience a aprender de sus errores).

  3. El problema que el video puede dejar de mostrar después de mucho tiempo.

De los tres errores solo (3) puede que no sea necesario corregirlos.

    
respondido por el Bent 17.10.2016 - 11:56
fuente
4

Aquí hay muchas respuestas que discuten la evaluación del costo del error que se corrige en lugar de dejarlo. Todos contienen un buen consejo, 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 insectos existentes enturbian las aguas para un desarrollo y mantenimiento continuo. Hacer que sus evaluadores realicen un seguimiento de varios errores "no solucionan" mientras navega por su software al tratar de encontrar errores nuevos hace que su trabajo sea más lento y más propenso a errores. Unos cuantos errores "no solucionarán" que probablemente no afectarán a los usuarios finales harán que el desarrollo continuo sea más lento y el resultado será más defectuoso.

    
respondido por el Buhb 17.10.2016 - 22:14
fuente
2

Una cosa que he aprendido en mis años de codificación es que un error volverá. El usuario final siempre lo descubrirá y le informará. Si arreglará el error o no es "simplemente" una cuestión de prioridad y fecha límite.

Hemos tenido errores importantes (en mi opinión, los más importantes) que se decidieron en contra de solucionar en una versión, solo para convertirse en un factor clave para la próxima versión porque el usuario final se topó con ella una y otra vez. Lo mismo viceversa: fuimos obligados a corregir un error en una función que nadie usa, pero fue útil para que la gerencia lo vea.

    
respondido por el Aleksandra 18.10.2016 - 09:39
fuente
1

Un post-it en el escritorio de un desarrollador senior en mi lugar de trabajo dice

  

¿Ayuda a alguien?

Creo que a menudo es un buen punto de partida para el proceso de pensamiento. Siempre hay muchas cosas que corregir y mejorar, pero ¿cuánto valor está agregando realmente? ... ya sea en usabilidad, confiabilidad, mantenibilidad, legibilidad, rendimiento ... o cualquier otro aspecto.

    
respondido por el topo morto 18.10.2016 - 00:46
fuente
1

Hay tres cosas aquí:

Principios

Este es un lado de la moneda. Hasta cierto punto, creo que es bueno insistir en corregir errores (o implementaciones incorrectas, incluso si "funcionan"), incluso si nadie lo nota.

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 como la recursión es un concepto muy difícil. Al corregir el error (y sudar a través de todo el trabajo adicional), tal vez aprende algo y lo recuerda, aunque solo sea para evitar el trabajo adicional en el futuro. Si la razón es que simplemente no tuvo tiempo suficiente, la administración podría aprender que los programadores hacen necesitan más tiempo para crear un código de mayor calidad.

  • El programador lo notó, pero lo consideró "no es un problema". Si se deja reposar, entonces se desarrolla una cultura de laissez-faire que, en última instancia, conducirá a los errores donde realmente duele. En este caso particular, a quién le importa. Pero, ¿qué pasa si el programador está desarrollando una aplicación bancaria la próxima vez y decide que una 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 corrija el error. Pero cuidado, hay pragmatismo, y luego hay pragmatismo. Un buen pragmatismo es si encuentra una solución rápida pero sólida y bien fundada para un problema. Es decir, evitas diseñar cosas en exceso, pero las cosas que realmente implementas aún están bien pensadas. El mal pragmatismo es cuando simplemente se piratea algo que funciona "solo así" y se romperá en la primera oportunidad.

Fallo rápido, falla duro

En caso de duda, falle rápido y falle.

Esto significa, entre otras cosas, que su código advierte la condición de error, no el entorno.

En este ejemplo, lo menos que puede hacer es hacerlo para que no se produzca el error de tiempo de ejecución duro ("profundidad de pila excedida" o algo así), al reemplazarlo por una excepción dura de la suya. Por ejemplo, podría tener un contador global y decidir arbitrariamente que se rescatará después de 1000 videos (o el número que sea lo suficientemente alto como para que nunca ocurra en el uso normal y lo suficientemente bajo como para que funcione en la mayoría de los navegadores). Luego dé a esa excepción (que puede ser una excepción genérica, por ejemplo, un 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

  • ... documentó el problema dentro del código.
  • ... lo convirtió en un problema determinista. Usted sabe que su excepción sucederá. No está en el capricho de los cambios en la tecnología del navegador subyacente (piense no solo en el navegador de la PC, sino también en los teléfonos inteligentes, tabletas o tecnología futura).
  • ... hizo que sea más fácil solucionarlo cuando eventualmente lo necesite. La fuente del problema se señala en su mensaje, obtendrá un retroceso significativo y todo eso.
  • ... aún no pierde el tiempo haciendo el manejo de errores "real" (recuerde que nunca espera que ocurra el error).

Mi convención es prefijar dichos 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 como ese en una GUI o en un archivo de registro, estoy seguro de que tengo un problema serio: después de todo, nunca esperé que ocurrieran. En este punto, entro en modo crítico (con una buena posibilidad de resolverlo de forma rápida y bastante fácil, ya que sé exactamente dónde ocurrió el problema, lo que me ahorra una gran cantidad de depuración falsa).

    
respondido por el AnoE 19.10.2016 - 15:08
fuente
0

Tres cosas vienen a la mente:

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 su ejemplo, al mismo tiempo pensé en la pérdida de memoria que representa la pila cada vez mayor y que podría hacer que su navegador sea más lento y más lento con cada recursión). Esta investigación exhaustiva a menudo toma más tiempo que corregir el error , así que prefiero corregir el error en la mayoría de los casos.

En segundo lugar , los errores tienen una tendencia a tener más impacto del que se cree al principio. Todos estamos muy familiarizados con el código de trabajo porque este es el caso "normal". 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 sobre cómo se comporta el código de trabajo que sobre cómo se comporta el código de buggy. Hay millones de libros sobre código de trabajo y lo que hará en cada situación. No hay casi nada sobre el comportamiento del código buggy.

La razón para esto es simple: los errores no son orden sino caos . A menudo les queda un rastro de orden (o lo dicen al revés: no destruyen la orden por completo), pero su naturaleza defectuosa es una destrucción de la orden que el programador quería. El caos mismo tiende a desafiar el ser estimado correctamente. Es mucho más difícil decir lo que hará un programa con un error que lo que hará un programa correcto simplemente porque ya no encaja en nuestros patrones mentales.

Tercer , 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: solucione el error, no debería llevar demasiado tiempo porque no es necesario rediseñar. De lo contrario :) En ese 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.

Todo lo que se dijo , los programas son cosas que usa la gente, y una característica faltante o un segundo error realmente engorroso en otros lugares puede tener prioridad sobre la solución del error. Por supuesto, entonces tome la manera pragmática y haga otras cosas primero. Pero nunca olvide que una primera estimación rápida del impacto de un error puede ser totalmente errónea.

    
respondido por el Alfe 19.10.2016 - 15:04
fuente
0

Probabilidad baja / Consecuencias leves = corrección de prioridad baja

  • Si la probabilidad de ocurrencia es muy baja
  • Si las consecuencias de la ocurrencia son leves
  • Entonces el error no representa una amenaza, entonces no es una solución de prioridad.

Pero esto no puede convertirse en una muleta para los desarrolladores perezosos ...

  • ¿Qué significa "muy baja ocurrencia"?
  • ¿Qué significa "consecuencias leves" incluso?

Para indicar 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 originalmente pensaron nunca sucederán, en realidad sucederán 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 rota y una intuición de proabilidad rota. La experiencia con problemas del mundo real y la experiencia con simulaciones extensas es la única forma que conozco para 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ás de que lo hagan. De esa manera, podrá confrontar su intuición con datos duros y refinarla.

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 poco clara, el sistema debitó al cliente un centavo menos que lo registrado en los registros. Descubrí el error porque hice informes para identificar las diferencias entre los registros y los equilibrios de la cuenta para hacer que el sistema de contabilidad sea más resistente. Nunca reparé este error porque la diferencia era muy pequeña. La diferencia se calculó diariamente y fue inferior a US $ 2.00 mensuales. Sucede que estábamos desarrollando un sistema completamente nuevo que en un año debería reemplazar al actual. No tiene sentido desviar recursos de un proyecto potencialmente rentable para arreglar algo que cuesta US $ 2.00 mensuales y fue sujeto a una medida de control apropiada.

Conclusión

Sí, hay errores que no necesitan solucionarse 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.

    
respondido por el Lucas 02.11.2016 - 10:08
fuente
-1

Creo que esto es hacer la pregunta incorrecta desde el principio.

La pregunta no es "¿Debo corregir este error o no debo solucionarlo?". Cualquier desarrollador tiene un tiempo limitado. Entonces, la pregunta es "¿qué es lo más útil que puedo hacer en una hora, cuatro horas o una semana?".

Si corregir ese error es lo más útil, ya que mejora el software en la mayor cantidad posible para la mayoría de las personas, entonces corrija el error. Si pudiera realizar mejoras mayores en otros lugares, agregando características que faltan personas o corrigiendo un error más importante, haga estas otras cosas. Y puntos de bonificación extra por cualquier cosa que haga que su desarrollo futuro sea más eficiente.

    
respondido por el gnasher729 20.10.2016 - 23:50
fuente
-2

Corrección de errores siempre es un overkill

Clasifiquemos la parte error primero.

¿Es un error honesto , por ejemplo, ¿Un error único o una variable que sigue las pruebas que escaparon? En este caso, espero que, además de "solucionar" el problema, también haya escrito nuevas pruebas unitarias, aprovechó la oportunidad para refactorizar el código cercano, donde todo lo último es trabajo útil .

Sin embargo, si en realidad se trata de un defecto de diseño como en su caso, debería reevaluar el diseño o, en el peor de los casos, desactivar esta característica.

Por lo tanto, no intentes simplemente arreglarlo .

Podría hacerlo peor, por supuesto, podría probar la metodología hack-upon-hack . El bucle de video es un hack (mala arquitectura y se conocen roturas). Puedes agregar un límite de bucle , de modo que después de N iteraciones (que has probado está por debajo del límite del navegador) el bucle finalice.

Las ramificaciones son obvias, ahora tienes que admitir tanto el código roto como el nuevo límite de bucle.

P.S. disculpas por la visión extrema.

P.P.S. Una nota sobre la terminología: no se puede "arreglar" un error. Bueno, quizás un veterinario podría, pero no vayamos allí ;-). Los problemas se resuelven o se "arreglan", mientras que los errores se eliminan o solucionan.

    
respondido por el Dima Tisnek 19.10.2016 - 13:46
fuente

Lea otras preguntas en las etiquetas