Las excepciones se manejan (Js)

Aunque pueda parecer algo muy evidente, quiero dedicar un artículo al manejo de excepciones o errores en Javascript.

En la medida de los posible si hay un error y nos podemos recuperar de él y continuar con nuestra aplicación, mejor. Por eso, hay varios métodos que nos pueden servir para este cometido:

  • Throw: Lanza un error y se para la ejecución.
  • Try: intenta ejecutar la función y, si tuviera algún error (throw)…
  • Catch: …lo captaría este catch y nos lo enseñaría.

Por ejemplo, tenemos esta función que lanza el error a través del throw:

Antes de continuar, tenemos que aclarar que en un caso real, normalmente no pondríamos el throw ahí, tan expuesto, sino en una condición, ya que si no, siempre se lanzaría el error y no nos serviría para controlar la aplicación. Sin embargo, para entender su funcionamiento, en este artículo vamos a hacerlo de esta manera para que siempre se lance y veamos hacia dónde va.

Dicho esto, ahora vamos a ejecutar lanzaError:

Como vemos en la consola, cuando se ejecuta la función, sólo se ejecuta el console.log que incluye la a, eso es porque tiene un throw inmediatamente después, que además de lanzar un error, detiene la ejecución y, por tanto ya no continúa con el console.log(‘b’). Además, nos está avisando de que hay un error no capturado.

Por lo tanto, por encima de esta función deberíamos tener otra que capture ese error (y así manejamos ese Uncaught), por ejemplo sería así:

Vamos por partes:

En esta función tenemos por un lado un método try, que lo que hace es “intentar” ejecutar lo que hay dentro, que en este caso son dos cosas:

  • nuestra función lanzaError()
  • un console.log

Por otro lado, tenemos un método catch, que recibe un parámetro “error”, que va a ser el throw de la función del nivel inferior, en este caso lanzaError(), es decir, que va a capturar ese error y nos lo va a mostrar, pero lo más importante de todo es que nuestra aplicación NO se va a detener, gracias a que hemos manejado ese error.

Así pues, si ejecutamos la función, nos aparece esto en la consola:

Vemos que la función lo primero que hace es ejecutar nuestro lanzaError(), con lo cual, nos muestra el a y, como existe un error, ya que la función anterior lo ha lanzado, pues ha entrado en el catch, lo ha capturado y nos lo muestra, y además nos muestra el otro console.log que tenía el catch.

Ejemplo con un callback

Aunque comprender lo anterior ya es suficiente, quiero mostrar un ejemplo de un try-catch con un callback como parámetro, simplemente para hacer varias pruebas y asimilar mejor el funcionamiento.

Tenemos por un lado nuestra función que lanza el error con throw:

Y por otro lado la función que maneja esos throws a través de un callback:

Hasta aquí todo bien. Ahora vamos a probar a ejecutar la función throws así:

throws(inferior());

¿Qué crees que pasará?

Que, debido a la norma del lenguaje que dice que una expresión se empieza a leer de dentro hacia afuera, lo que ha ocurrido aquí es que se ha ejecutado inferior() antes de entrar en throws(). Así pues, inferior tiene un console.log(‘a’) y un throws, que en ese caso no se ha podido capturar porque no ha llegado a entrar en throws, por lo tanto, aparece como Uncaught error.

Si quisiésemos obtener el comportamiento esperado tendríamos que ejecutarlo así:

throws(inferior);

Y ya obtendríamos:

Conclusión

Es importante manejar los errores y escenarios posibles en nuestra aplicación, sin embargo, el uso del throw-try-catch debería limitarse a aquellas situaciones que son excepcionales. Para el resto de situaciones podemos manejarlo de otras maneras, como por ejemplo condicionales (if, else…).

If something does not work, ACT. Yes, you! That’s why I’m now #Developer at @vmware . Formerly @kairos_ds .Constantly absorbing knowledge. Proud #Adalaber

If something does not work, ACT. Yes, you! That’s why I’m now #Developer at @vmware . Formerly @kairos_ds .Constantly absorbing knowledge. Proud #Adalaber