Registro de errores personalizado en JavaScript

Sistema de logging personalizado en aplicaciones JavaScript y las limitaciones de la consola del navegador .

registro-errores-personalizado

En el desarrollo de aplicaciones web es muy importante estar al corriente de los problemas que nos alerta la consola del navegador. Sin embargo, esa información suele quedarse en el mismo navegador del usuario que mira nuestra web y para nosotros es inaccesible cuando algo falla en producción. Además, lo que vemos como errores (los típicos Uncaught ReferenceError, TypeError, etc.) no siempre es todo lo que necesitamos.

Por eso tiene sentido agregar una capa de registro personalizada. Nos permite interceptar eventos clave, capturar más contexto y enviar los datos a servicios que sí podemos consultar después, como Sentry, TrackJS o incluso una API propia.

¿Por qué extender la gestión de errores del navegador?

El navegador hace un buen trabajo mostrando errores en tiempo real mientras desarrollamos una página web. Pero en producción, salvo que tengamos acceso al dispositivo del usuario, no podemos qué está ocurriendo. Además:

  • No todos los errores generan una excepción visible.
  • Las advertencias (console.warn) y mensajes informativos (console.info) también pueden indicar problemas futuros.
  • No siempre se incluye el contexto (estado de la aplicación, usuario, dispositivo, etc.)
  • No hay persistencia ni agregación sin una solución externa.

Capturar y registrar errores de manera personalizada permite reaccionar cuando los usuarios se vean afectados. También ayuda a identificar patrones o fallos recurrentes que, de otro modo, pasarían desapercibidos.

Qué se suele hacer con los errores capturados

Generalmente, se recogen los errores globales con window.onerror o window.addEventListener('error', ...), se enriquecen con información adicional (como el navegador, la URL actual, el usuario autenticado si lo hay) y luego se envían a servicios como:

  • TrackJS: muy centrado en frontend, fácil de integrar.
  • Sentry: popular tanto para frontend como backend, permite trazas y seguimiento de sesiones.
  • LogRocket: graba sesiones completas, lo que permite ver el error en contexto.
  • Servicios personalizados: se puede construir un endpoint para registrar los errores en nuestra propia base de datos.

También conviene filtrar los errores para evitar ruido (por ejemplo, errores de extensiones del navegador o dominios externos).

Captura básica de errores con JavaScript

Un ejemplo mínimo de cómo registrar errores no capturados y enviarlos mediante una api a un servicio propio podría ser el siguiente:

window.onerror = function(message, source, lineno, colno, error) {
const errorData = {
message,
source,
lineno,
colno,
stack: error?.stack || null,
userAgent: navigator.userAgent,
url: window.location.href,
timestamp: new Date().toISOString()
};
// Enviar a un endpoint propio o a un servicio externo
fetch('/api/log-error', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(errorData)
});
};

Además, podemos capturar errores en promesas no gestionadas:

window.addEventListener('unhandledrejection', function(event) {
const errorData = {
reason: event.reason,
type: 'unhandledrejection',
timestamp: new Date().toISOString()
};
fetch('/api/log-error', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(errorData)
});
});

Y si queremos registrar advertencias también, sobreescribiendo console.warn para que nos envía el mensaje cuando ocurra un warning:

const originalWarn = console.warn;
console.warn = function(...args) {
fetch('/api/log-warning', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: 'warn',
args,
timestamp: new Date().toISOString()
})
});
originalWarn.apply(console, args);
};

Consideraciones adicionales

  • No deberíamos registrar errores de desarrollo en el entorno local.
  • Conviene anonimizar datos sensibles.
  • Es útil agrupar errores por tipo, componente, o frecuencia.
  • Algunas herramientas permiten añadir trazas personalizadas (breadcrumbs) para reconstruir el flujo antes del fallo.

Conclusión

El registro de errores personalizado nos da visibilidad sobre lo que realmente ocurre en producción. Nos permite detectar problemas antes de que escalen o errores que se nos habían escapado, reunir más contexto para diagnosticar y, en algunos casos, incluso anticipar errores gracias al análisis de advertencias. Aunque puede empezar con unas pocas líneas de código, su impacto a largo plazo en la estabilidad del proyecto es significativo.