Blog

  • try/catch me… if you can

    Todo lenguaje que se precie tiene un mecanismo para capturar excepciones. Ya sabes, esos errores que hacen nuestra vida más emocionante en los momentos más inoportunos. Y todo programador digno de tal nombre sabe usar la gestión de excepciones a su favor. Algunos de maneras… imaginativas. Para valores muy extremos de “imaginativas”.

    La gestión (adecuada) de excepciones hace nuestra vida mejor, sin ninguna duda. Sin embargo, lo que me encontré hace tiempo en un proyecto desarrollado en JavaScript por un programador de C# con más entusiasmo que conocimientos ocasionó más de un dolor de cabeza a la joven programadora encargada de su mantenimiento.

    ¿Los síntomas del problema? Aparte de los mencionados dolores de cabeza, el programa se colgaba. Sin dar errores. Ni aviso de quince días. Ni tan siquiera un carraspeo avergonzado. Vale, estoy exagerando. El programa mostraba este mensaje.

    El método IsBlocked(), donde se muestra esta alerta, es el típico método promiscuo que se lanza a una orgía de llamadas asíncronas a otros métodos que llaman a otros métodos que hacen otras llamadas asíncronas hasta que, de repente, nos salta un alert en pantalla.

    Uno de esos métodos ha dado un error, que ha sido interceptado por el catch y “escalado” hacia arriba, catch tras catch hasta llegar a la línea 1572 del archivo donde muestra el mensaje. Lo que sigue a continuación suele ser una divertida sesión de depuración aderezada con recordatorios a la madre del programador original.

    Una correcta gestión de excepciones no sólo es deseable, sino que ayuda a mantener la salud mental. El problema surge cuando la gestión de excepciones consiste en una serie de métodos que envían el error hacia arriba esperando que alguien lo recoja. Si nadie lo hace o si, como en este caso, la respuesta es que ha habido un error en un método que no es que realmente falla nos espera un mundo de dolor e imprecaciones.

    Pero ¿por qué salta una excepción y qué significa? En un mundo ideal los programas nunca tienen errores, los servidores responden a las peticiones con los datos que se esperan y los arrays están correctamente dimensionados, entre otras muchas partes móviles que pueden griparse en un momento dado.

    Una excepción es, literalmente, que ha pasado algo que el programa no sabe como manejar. La gestión de excepciones a base de try/catch(“intenta hacer esto”/“pilla el error”) captura esas situaciones “excepcionales” y le dice al programa que algo ha pasado (ese parámetro que se pasa a la parte catch()). Si el “pilla el error” correspondiente al “intento de hacer algo” no hace nada, la excepción se pasa al “pillador” de la función o método desde el que se llamo al código que ha fallado. Y así sucesivamente hasta que se hace algo con esa excepción.

    Si el sistema está bien organizado es una gran ayuda. Si, como pasa muchas veces, no hay nadie para “pillar” las excepciones, el resultado es un error que ha sido enmascarado. O directamente ignorado. El programa no hace lo que debería y nadie sabe la causa, porque no se reciben errores en el depurador.

    Porque esa es otra, el depurador (en el navegador, en este caso) no va a devolver una excepción que ya está siendo, en teoría, gestionada por el código. En lugar de mostrarte un mensaje de ha pasado esto en tal línea se calla, porque alguien le ha dicho que ya se encarga de esas cosas.

    En el ejemplo que nos ocupa, se ejecutan siete métodos con su correspondiente catch (e) { }. Es decir, que no hacen nada más que mandar el error hacia arriba. Hasta que un método, lo más lejos posible del error original, dice que ha tenido un error. Pero no es el método que se queja quien ha fallado, sino otro siete niveles más abajo. Para que luego digan que programar es aburrido.

    Las soluciones a estos despropósitos son múltiples. Una, implementar correctamente la gestión de excepciones. La segunda, colarse por en medio y, si la plataforma lo permite, añadir un sistema de excepciones “paralelo”. Cuando se está trabajando con código perpetrado más que programado es conveniente usar el sistema “paralelo”.

    Implementar este sistema es trivial en JavaScript. Basta con añadir un handler que se ejecuta cada vez que sucede un error. Por defecto, el depurador sólo menciona los errores que no son capturados por la gestión de excepciones, pero, con este handler estamos forzando a responder a todos los errores, gestionados o no.

        window.onerror = function (strMessage, strURL, strLine) {
            alert(strMessage + '<br/>' + strURL + ' - ' + strLine);
            return true;
        };

    El handler va a recibir el texto del mensaje, y el archivo y línea donde se ha generado el error. Mostrar un alert, o escribir el error a la consola, o hacer cualquier cosa con él ya es decisión del programador.

    Volviendo al ejemplo, el error que hace saltar una excepción en la línea 1572 del archivo se produce, realmente, en la línea 2437 del mismo, varias llamadas asíncromas más tarde. Este mensaje si es realmente informativo y nos ahorra perseguir todas las llamadas hasta que una de ellas falle. La otra opción, por supuesto, es buscar en todo el código cada catch y “rellenarlo” con un mensaje o una alerta. Pero si hay que mantener o arreglar código perpetrado es más rápido tirar por la calle de en medio.

  • Emprender “a pachas”

    “Estoy investigando modelos asociativos para lanzar productos “a pachas” entre varios. O algo así.”

    No fue un twit al albur, sino algo a lo que llevo tiempo dando vueltas. Y que creo que puede interesar a más gente.

    Imaginemos que, junto con un diseñador y otro programador, hago un proyecto con visos de ser colocado en alguna Store. Los tres somos autónomos. Se hace un contrato privado, el equivalente a un acuerdo de accionistas de una startup, para dejar las cosas claras.

    Pero luego llega el momento de subir eso a la Store. Sólo lo puede subir uno de los tres. Que es quien recibirá los ingresos. Y luego debe liquidar con los otros dos, incluyendo retenciones, ivas y venías. Al final no salen las cuentas entre papeleos y tonterías.

    He conocido a empresarios que tienen los recursos para montar un proyecto con otros a base de invertir lo necesario para constituir la sociedad y repartir gastos y beneficios (si los hay). Pero en el mundo real, el de los mindundis 2.0, esto no es así de simple. No hay recursos. Y sí demasiada burocracia.

    No es plan crear una empresa invirtiendo un capital social para un proyecto que puede o no dar dinero. Somos autónomos, no gente con dinero.

    ¿Qué opciones podrían tener los presuntos emprendedores para hacer este tipo de proyectos sin meterse en papeleos y gastos innecesarios? En el país de la Marca Apaña más bien pocas.

  • La trampa del diseño “responsive”

    Como siempre, esto empieza porque alguien cercano a la par que incauto me enseña un proyecto. En este caso una landing page montada rápidamente con un template para un trabajo de fin de carrera. Un template con todos los extras “requeridos”. Incluyendo la adaptación del diseño al ancho del dispositivo. Lo que se llama “responsive design”. Es decir, que el diseño responde al contexto en que se muestra y se adapta al mismo.

    (more…)

  • Este no es el producto que están buscando

    Un desarrollador y, sin embargo, amigo, me tiene entretenido de vez en cuando revisando un proyecto. Las revisiones suelen consistir en sesiones con café en las que este joven, la gerente y algún espontáneo hablan de cualquier cosa mientras yo le digo que no a todo. Product Managing at its best.

    En la última sesión el proyecto, que originalmente hacía una cosa, había crecido para hacer tres o cuatro más o menos relacionadas. El joven ha adquirido el típico retrovirus MS3WTF1 conocido popularmente como “Bloatware”. Este virus es más común de lo que parece y encuentra su caldo de cultivo en la mente de

    1. Programadores que están aprendiendo,
    2. vendedores tras tomar unas copas con un cliente y
    3. empresas que organizan grupos de estudio.

    Sin embargo no todo está perdido. Especialmente el tiempo invertido en añadir features (poyaques en español). Veamos, pues, como afrontar el problema en cuestión: un proyecto que engorda más allá de lo necesario.Hablamos de un proyecto para iOS.

    (more…)

  • Loader… si hace falta

    Y va el joven @jmoreno78, se pone y dice: “Maestro, es recomendable indicar que se está cargando una combo vía ajax mediante un engranaje girando o algo así?”

    Si lo haces rapidito no. Pero si pasas de 2-3sg es conveniente. Una forma de hacerlo es creando un objeto con sólo dos métodos, start() y stop(). Llamas al start antes de tu ajax y al stop() cuando tienes el resultado. El truco está en que, internamente, sólo se muestra el loader si han pasado dos segundos.

    (more…)