Resumen

Cuando trabajas con código asíncrono en Node.js, el manejo de errores se convierte en un reto real. El clásico try catch no funciona dentro de callbacks porque el error ocurre después de que el bloque ya terminó su ejecución. Para resolver esto, Brian Dagg, creador de Node.js, propuso una convención que se volvió estándar en todo el ecosistema: los error first callbacks.

¿Por qué el try catch no funciona con código asíncrono?

El try catch es una estructura que permite intentar ejecutar un bloque de código y, si ocurre un error, atraparlo en el bloque catch para manejarlo de forma controlada. Funciona perfectamente con código síncrono [0:22]. Por ejemplo, si intentas acceder a una propiedad de una variable indefinida, el catch atrapa ese error y puedes mostrar un mensaje en consola.

El problema aparece con el código asíncrono [1:07]. Si dentro de un try colocas un setTimeout que lanza un error después de un segundo, el try catch ya terminó de ejecutarse cuando el callback finalmente se dispara. El error queda sin manejar y puede crashear la aplicación. Ese catch nunca se ejecuta porque la operación asíncrona vive fuera del alcance temporal del bloque.

¿Qué es la convención error first callbacks?

Para solucionar este vacío, se estableció una convención clara [1:35]:

  • El primer argumento de cualquier callback siempre es el error.
  • El segundo argumento es el resultado de la operación.
  • Si no hay error, el primer argumento es null.

Esta estructura se aplica, por ejemplo, al leer archivos con la librería fs de Node.js [1:52]:

javascript fs.readFile('archivo.txt', (err, data) => { if (err) { console.error(err.message); return; } console.log('Contenido:', data); });

El patrón también se usa al escribir archivos con fs.writeFile [3:06]:

javascript fs.writeFile('salida.txt', 'Hola mundo', (err) => { if (err) { console.error(err.message); return; } console.log('Archivo guardado correctamente'); });

La estructura siempre es la misma: una función con un callback donde primero verificas el error y luego procesas el resultado.

¿Por qué fue tan importante esta convención?

Tres razones fundamentales la convirtieron en pilar del desarrollo con Node.js [2:28]:

  • Manejo explícito de errores: cada callback obliga al desarrollador a considerar qué pasa cuando algo falla.
  • Control manual del flujo: decides exactamente cómo reaccionar ante cada situación.
  • Compatibilidad entre librerías: todos los desarrolladores sabían cómo se comportaban los callbacks, lo que creó consistencia en todo el ecosistema.

¿Cuál es el error más común al usar error first callbacks?

Uno de los errores más frecuentes al comenzar con este patrón es olvidar el return después de manejar el error [3:30]. Sin él, el código sigue ejecutándose con un resultado inválido.

javascript // Incorrecto: falta el return processFile((err, data) => { if (err) { console.error(err.message); } // Este código se ejecuta aunque haya error console.log(data.toString()); // TypeError: data es null });

javascript // Correcto: el return corta la ejecución processFile((err, data) => { if (err) { console.error(err.message); return; // Aquí se detiene } console.log(data.toString()); });

El return actúa como un cortafuegos que impide que el código continúe procesando datos que no existen. Sin él, obtendrás un TypeError porque los datos son null.

¿Cuáles son los límites de esta convención?

La convención error first es un contrato claro que hace que todos los callbacks se comporten de la misma manera [4:18]. Sin embargo, tiene una limitación importante: funciona bien para una sola operación asíncrona. Cuando necesitas encadenar varias operaciones, el código se complica rápidamente y aparece lo que se conoce como callback hell, el famoso infierno de los callbacks.

Si ya dominas el patrón error first, comparte en los comentarios cuál ha sido tu experiencia manejando errores en código asíncrono y cómo te has enfrentado al encadenamiento de múltiples callbacks.