Estándar de Codificación y Gestión de Errores en Arquitecturas de Microservicios
- Mauricio ECR
- Convenciones de código
- 18 Jun, 2025
En el ecosistema de aplicaciones web modernas, la arquitectura de microservicios distribuidos se ha consolidado como un paradigma dominante. Su flexibilidad, escalabilidad y resiliencia son innegables. Sin embargo, esta distribución introduce una complejidad significativa en la gestión de estados y, especialmente, en el manejo de errores. Cuando una operación involucra a múltiples servicios, identificar la causa raíz de un fallo puede convertirse en una tarea titánica, afectando la experiencia del usuario, los tiempos de resolución y la mantenibilidad del sistema.
Este documento establece un estándar completo y directamente aplicable para la codificación, documentación y gestión de errores visibles al usuario final. El objetivo es crear un marco de trabajo robusto que, aunque inicialmente se implementará en un entorno de backend con Java (Spring Boot) y frontend con Angular, ha sido diseñado con un enfoque agnóstico al lenguaje para garantizar su longevidad y adaptabilidad a futuras tecnologías.
Adoptar este estándar permitirá no solo presentar mensajes de error claros y útiles al usuario, sino también establecer una base documental sólida que facilite la observabilidad, la trazabilidad y la colaboración entre equipos de desarrollo, QA y soporte técnico.
El Estándar Detallado
1. Filosofía y Principios Fundamentales
Antes de detallar la implementación, es crucial entender los principios que guían este estándar:
- El Error como Ciudadano de Primera Clase: Los errores no son un caso excepcional, sino una parte inherente del flujo de una aplicación. Deben ser diseñados, documentados y probados con el mismo rigor que las funcionalidades exitosas.
- Claridad para el Usuario, Detalle para el Desarrollador: La información presentada al usuario final debe ser concisa, clara, traducible y orientada a la acción. Por el contrario, la información registrada para los equipos técnicos debe ser rica en detalles para permitir un diagnóstico rápido y preciso.
- Seguridad por Opacidad: Los códigos y mensajes de error públicos nunca deben revelar detalles de la infraestructura interna, nombres de clases, trazas de pila (stack traces) o cualquier información que pueda ser explotada por un actor malicioso.
- Trazabilidad Extrema: Cada error debe ser unívocamente identificable y correlacionable a través de los distintos servicios y sistemas de observabilidad (logs, métricas, trazas distribuidas).
2. Formato del Código de Error
Todo error visible al usuario final o que cruce los límites de un microservicio deberá ser identificado por un código único y opaco. Este código actúa como una clave inmutable que desacopla el error en sí de su representación (el mensaje).
La estructura propuesta es: MSS-ECNNN[-EXTCODE]
-
MSS(MicroService Short-identifier): Identificador numérico único de 3 dígitos asignado a cada microservicio. Esta asignación debe ser gestionada en un registro centralizado para evitar colisiones.- Ejemplo:
101para “Servicio de Autenticación”,205para “Servicio de Pedidos”.
- Ejemplo:
-
EC(Error Category): Código alfabético de 2 letras que clasifica la naturaleza del error. Esto permite un filtrado y análisis rápido. (Ver sección 3 para el catálogo de categorías).- Ejemplo:
IVpara “Validación de Entrada”,BRpara “Regla de Negocio”.
- Ejemplo:
-
NNN(Numeric Sequence): Secuencia numérica de 3 dígitos, única dentro del microservicio para esa categoría. Se recomienda iniciar en001y aumentar de forma secuencial.- Ejemplo:
001,002,047.
- Ejemplo:
-
[EXTCODE](External Code - Opcional): Componente opcional para encapsular errores originados en servicios de terceros. Proporciona una correlación directa sin exponer el formato original del tercero.- Formato:
EXT_<ID_SERVICIO>_<CODIGO_ERROR_ORIGINAL> ID_SERVICIO: Un identificador corto y predefinido para el servicio externo (ej.STRIPE,SENDGRID,AWS_S3).CODIGO_ERROR_ORIGINAL: El código de error devuelto por el servicio externo, sanitizado para ser compatible con la URL (ej. reemplazando espacios o caracteres especiales por_).- Ejemplo:
205-DP003-EXT_STRIPE_card_declined
- Formato:
Ejemplo completo: 205-BR001 representa el primer error de “Regla de Negocio” definido en el microservicio “Pedidos” (ID 205).
3. Clasificación de Errores Comunes
La estandarización de categorías (EC) es fundamental para la observabilidad y la generación de métricas. El catálogo inicial es el siguiente:
| Código | Categoría | Descripción |
|---|---|---|
IV | Input Validation | Errores relacionados con la validación de datos de entrada (formato, rango, campos obligatorios). Suelen ser errores del tipo 400 Bad Request. |
AU | Authentication & Authorization | Fallos de autenticación (token inválido, credenciales incorrectas) o autorización (sin permisos para la acción). Errores 401 Unauthorized o 403 Forbidden. |
BR | Business Rule | Violación de una regla de negocio específica. La solicitud es sintácticamente correcta pero semánticamente inválida en el contexto actual (ej. stock insuficiente). Suele ser un 409 Conflict o 422 Unprocessable Entity. |
DP | Dependency Failure | Un servicio externo del que depende el microservicio no está disponible o ha devuelto un error (otra API interna, base de datos, sistema de colas). Errores del tipo 502 Bad Gateway o 503 Service Unavailable. |
SY | System Error | Errores inesperados o no controlados en el servidor (excepciones RuntimeException, NullPointerException, etc.). Siempre deben ser investigados. Corresponden a un 500 Internal Server Error. |
NT | Network & Timeout | Errores de comunicación, ya sea porque una dependencia no respondió a tiempo o por problemas en la red. Corresponde a un 504 Gateway Timeout. |
CF | Configuration Error | El servicio no puede iniciarse o funcionar correctamente debido a una configuración faltante o incorrecta (variables de entorno, secretos, etc.). |
NF | Not Found | El recurso solicitado no existe. Corresponde a un 440 Not Found. |
4. Catálogo Inicial de Códigos de Error
A continuación, se presenta un catálogo de ejemplo con 10 códigos para dos microservicios hipotéticos: Gestión de Usuarios (ID: 101) y Procesamiento de Pedidos (ID: 205).
| Código | Mensaje usuario | Descripción técnica | Severidad | Estado | Acción esperada | Servicio externo (si aplica) |
|---|---|---|---|---|---|---|
| 101-IV001 | El correo electrónico proporcionado no tiene un formato válido. Por favor, revísalo. | El campo email en el DTO de registro de usuario no supera la validación de la expresión regular ^(.+)@(.+)$. | Baja | Activo | Usuario: Corregir el formato del email. Frontend: Realizar validación en cliente para prevenir el error. | N/A |
| 101-AU001 | Tu sesión ha expirado. Por favor, inicia sesión de nuevo. | El JWT recibido en la cabecera Authorization ha caducado. La fecha de expiración (exp) es anterior a la fecha actual. | Media | Activo | Sistema: Redirigir al usuario a la página de login. Usuario: Volver a introducir sus credenciales. | N/A |
| 101-AU002 | No tienes permisos para realizar esta acción. Contacta al administrador si crees que es un error. | El usuario autenticado, extraído del token, no posee el rol requerido (ROLE_ADMIN) para acceder al endpoint. | Media | Activo | Frontend: Ocultar o deshabilitar la opción que provoca el error. Soporte: Verificar los roles del usuario si este levanta un ticket. | N/A |
| 101-BR001 | El correo electrónico ya está registrado en nuestra plataforma. Intenta iniciar sesión. | Se intentó crear un usuario con un email que ya existe en la tabla users de la base de datos (violación de UNIQUE constraint). | Baja | Activo | Usuario: Usar la opción “recuperar contraseña” o iniciar sesión. Frontend: Ofrecer un enlace directo a la página de login. | N/A |
| 205-IV001 | El identificador del producto no es válido. Debe ser un número positivo. | El productId recibido en la línea de un pedido es nulo, cero o negativo. La validación @Positive falló en el DTO. | Baja | Activo | Usuario: Informar del error. Es un caso raro que indica un bug en el frontend. Desarrollo: Investigar cómo se pudo enviar un ID inválido desde el cliente. | N/A |
| 205-BR001 | No hay suficiente stock para el producto ‘Nombre del Producto’. Solo quedan X unidades. | La cantidad solicitada de un producto es mayor que el stock disponible registrado en la base de datos para ese productId. | Media | Activo | Usuario: Reducir la cantidad del producto o eliminarlo del carrito. Sistema: El mensaje debe incluir el stock actual para ser útil. | N/A |
| 205-BR002 | No se pueden añadir productos de diferentes vendedores en un mismo pedido. | La lógica de negocio impide mezclar productos de sellerId distintos en una sola transacción para simplificar la logística. | Media | Activo | Usuario: Finalizar la compra actual y crear un nuevo pedido para los otros productos. Frontend: Mostrar una advertencia al intentar añadir un producto incompatible. | N/A |
| 205-DP001 | El servicio de inventario no está respondiendo. Por favor, inténtalo de nuevo en unos minutos. | La llamada HTTP al microservicio de Inventario (ID 310) para verificar el stock ha resultado en un timeout o error 5xx. | Alta | Activo | Sistema: Implementar un reintento con exponential backoff. Si persiste, activar un circuit breaker. Soporte: Revisar el estado del servicio de Inventario. | N/A |
| 205-DP002 | Tu pago no pudo ser procesado por el proveedor. Razón: Fondos insuficientes. | La pasarela de pagos (Stripe) devolvió un error 402 Request Failed con el código card_declined y el motivo insufficient_funds. | Media | Activo | Usuario: Intentar con otro método de pago o verificar los fondos de su tarjeta. Sistema: No reintentar automáticamente. Invalidar el pedido. | EXT_STRIPE_insufficient_funds |
| 205-SY001 | Ha ocurrido un error inesperado al procesar tu pedido. Nuestro equipo ya ha sido notificado. | Se ha capturado una NullPointerException no esperada en la clase OrderProcessingService al calcular los impuestos. Se ha creado una alerta en Sentry/Datadog. | Alta | Activo | Sistema: Registrar el trace_id y toda la información de la petición. Desarrollo: Priorizar la corrección de este bug. Usuario: Reintentar más tarde o contactar a soporte con el trace_id si se le muestra. | N/A |
5. Documentación y Centralización
La documentación es lo que transforma este estándar de una idea a una herramienta útil.
- Estructura de Archivos: Cada microservicio debe incluir en su repositorio un archivo
docs/errors/errors.md. Este archivo contendrá la tabla completa de errores que el servicio puede generar. - Control de Versiones: El archivo
errors.mddebe ser versionado junto con el código fuente del microservicio. Cualquier adición o modificación de un código de error debe formar parte de un Pull Request, permitiendo su revisión. - Formato de Documentación: Se utilizará la tabla Markdown definida en la sección anterior. Este formato es fácil de leer para humanos y de parsear por máquinas.
Ejemplo de microservice-orders/docs/errors/errors.md:
Catálogo de Errores - Servicio de Pedidos
- Nombre Lógico: Servicio de Procesamiento de Pedidos
- ID del Microservicio: 205
| Código | Mensaje usuario | Descripción técnica | Severidad | Estado | Acción esperada | Servicio externo (si aplica) |
|---|---|---|---|---|---|---|
| 205-IV001 | El identificador del producto no es válido. Debe ser un número positivo. | El productId recibido en la línea de un pedido es nulo, cero o negativo. La validación @Positive falló en el DTO. | Baja | Activo | Usuario: Informar del error. Desarrollo: Investigar cómo se pudo enviar un ID inválido. | N/A |
| … | … | … | … | … | … | … |
6. Recomendaciones para Centralización y Escalabilidad
Para que el estándar sea efectivo en una organización grande, se recomienda:
- Repositorio Central de Errores: Un pipeline de CI/CD debería agregar los archivos
errors.mdde todos los microservicios tras cada release exitosa en un repositorio central o una página de Confluence/Wiki. Esto crea un único punto de verdad para que los equipos de QA, Soporte y Frontend puedan consultar cualquier código de error sin necesidad de acceder a los repositorios individuales. - Automatización y Linters: El pipeline de CI/CD debe incluir pasos para:
- Validar la Unicidad: Asegurar que no existan códigos
MSS-ECNNNduplicados dentro del mismo microservicio. - Validar el Formato: Comprobar que todos los nuevos códigos sigan la estructura definida.
- Detectar Nuevos Servicios Externos: Lanzar una advertencia si se añade un
EXTCODEcon un<ID_SERVICIO>no registrado previamente, para asegurar que se documente centralmente.
- Validar la Unicidad: Asegurar que no existan códigos
- Generación de Artefactos: Se pueden crear scripts que lean estos archivos
.mdpara generar automáticamente artefactos útiles, como:- Enums de TypeScript para el frontend, permitiendo un manejo de errores tipado (
case ErrorCodes.USER_EMAIL_EXISTS:). - Clases de constantes en Java para el backend.
- Plantillas para sistemas de tickets (Jira, Zendesk).
- Enums de TypeScript para el frontend, permitiendo un manejo de errores tipado (
Conclusión
Este estándar de codificación y gestión de errores proporciona un marco de trabajo unificado y resiliente, diseñado para escalar con la complejidad de una arquitectura de microservicios. Al tratar los errores como un componente central del diseño de software, logramos múltiples beneficios:
- Mejora la Experiencia del Usuario (UX): Los mensajes son claros, consistentes y orientados a la acción.
- Agiliza la Resolución de Incidencias: Los códigos únicos y la documentación detallada permiten a los equipos de soporte y desarrollo identificar y solucionar problemas rápidamente.
- Potencia la Observabilidad: La estructura de códigos y categorías facilita la creación de dashboards, alertas y métricas significativas sobre la salud del sistema.
- Aumenta la Seguridad: La opacidad de los códigos previene la fuga de información sensible de la infraestructura.
Futuras Líneas de Aplicación:
- Integración con Plataformas de Observabilidad: Enriquecer automáticamente las trazas distribuidas (ej. en Jaeger o Datadog) con la “Descripción Técnica” del error a partir de su código.
- Desarrollo de un “Servicio de Errores”: Una pequeña API central que, dado un código de error, devuelva su documentación completa, incluyendo el mensaje de usuario localizado en diferentes idiomas.
- Generación de SDKs de Cliente: Automatizar la creación de librerías para diferentes lenguajes (JS/TS, Python, Go) que encapsulen la lógica de manejo de estos códigos de error estandarizados.
La adopción disciplinada de este estándar no es una carga adicional, sino una inversión estratégica en la calidad, mantenibilidad y escalabilidad a largo plazo de la plataforma.