Día 7/30: Patrón diseño AWS - ¿Dónde se perdieron 41.000 mensajes?

Descubre cómo un simple try/catch en una función Lambda provocó la pérdida silenciosa de 41.000 notificaciones en una plataforma SaaS multiinquilino.

martes, 28 de julio de 2026 • 6 min de lectura • Equipo Q2BSTUDIO

El peligro de ocultar errores con try/catch

En el desarrollo de arquitecturas cloud, a menudo nos encontramos con incidentes que parecen desafiar la lógica. Uno de los casos más instructivos ocurrió en una plataforma SaaS multi-tenant que perdió 41.000 notificaciones sin dejar rastro aparente. Analicemos qué sucedió y qué lecciones podemos extraer para diseñar sistemas más robustos.

El escenario es el siguiente: una plataforma envía todas sus notificaciones en segundo plano (email, SMS, webhooks) a través de una cola SQS estándar. Una función Lambda consume los mensajes mediante un mapeo de origen de eventos. El equipo configuró correctamente una cola de mensajes fallidos (DLQ) con maxReceiveCount de 5 y una alarma sobre la profundidad de la DLQ. Todo parecía en orden.

El viernes a las 6 PM se despliega una actualización de rutina con dos cambios: primero, la actualización del SDK del proveedor de email que rompe la búsqueda de credenciales; segundo, una mejora de robustez que envuelve el cuerpo del handler en un try/catch que registra cualquier excepción y retorna normalmente, con el comentario 'así una notificación mala no envenena todo el lote'. El sábado a las 9 AM el equipo de soporte descubre que ningún cliente recibió notificaciones durante la noche: 41.000 mensajes perdidos. Las métricas de CloudWatch no muestran errores de función, la profundidad de la cola es cero, la DLQ está vacía, la alarma nunca saltó. Todos los paneles están en verde. ¿Dónde fueron a parar los mensajes?

Antes de revelar la respuesta, evaluemos las opciones presentadas. La opción A sugiere que los mensajes cruzaron un umbral interno de conteo de recepciones y SQS los eliminó. No existe tal mecanismo: el conteo de recepciones solo dirige mensajes a una DLQ mediante una política de redrive; SQS nunca elimina basándose en el número de recepciones. La opción C plantea que expiró el período de retención de la cola. La retención por defecto es de 4 días; los mensajes de unas horas no pueden caducar. Además, la expiración no explicaría un perfil de cero errores y DLQ vacía. La opción D supone que el despliegue deshabilitó el mapeo de origen de eventos, pero una cola no consumida mostraría profundidad creciente. Una cola en cero sin errores indica que los mensajes fueron recibidos, 'procesados' y eliminados. La opción B es la correcta: el handler capturó cada excepción y devolvió éxito; Lambda reportó una invocación limpia, por lo que el mapeo de origen de eventos llamó a DeleteMessage en cada mensaje del lote. Los mensajes se eliminaron legítimamente, una invocación verde a la vez.

El problema es conocido como 'swallowing exceptions' o 'excepciones tragadas'. Al envolver todo el código en un try/catch que solo registra el error pero no relanza la excepción ni marca el mensaje como fallido, el handler siempre retorna éxito. Lambda interpreta que el procesamiento fue correcto y elimina los mensajes de la cola. La DLQ nunca recibe nada porque nunca se supera el maxReceiveCount; cada mensaje se procesa una sola vez (con éxito desde la perspectiva de Lambda). El registro de errores en logs queda oculto si no se monitorean adecuadamente; en este caso, los logs contenían las excepciones, pero nadie los revisó hasta después del incidente.

Este incidente subraya varios principios de diseño en arquitecturas cloud. Primero, el manejo de errores debe ser intencional. Un try/catch genérico que silencia fallos es peligroso; la excepción debe propagarse para que el mensaje pueda reintentarse o enviarse a la DLQ. Segundo, la monitorización debe incluir no solo errores de función, sino también métricas de cola, DLQ y logs no esperados. Tercero, las pruebas de integración deben cubrir escenarios de fallo, especialmente después de cambios en dependencias externas.

En Q2BSTUDIO, como empresa de desarrollo de software y tecnología, entendemos que la fiabilidad en sistemas distribuidos es crítica. Nuestra experiencia en cloud AWS/Azure nos ha enseñado a implementar patrones como el de cola de mensajes fallidos con reintentos controlados, circuit breakers y observabilidad basada en métricas y alarmas. Además, integramos automatización de procesos para garantizar que los despliegues no introduzcan regresiones silenciosas.

Para evitar este tipo de desastres, recomendamos las siguientes buenas prácticas: nunca atrapar excepciones sin relanzarlas a menos que esté explícitamente justificado; utilizar un middleware de manejo de errores a nivel de framework; instrumentar la aplicación con métricas personalizadas (como contadores de excepciones); establecer alarmas sobre la profundidad de la DLQ y sobre la tasa de mensajes eliminados sin error aparente; y realizar despliegues progresivos con monitoreo en tiempo real.

El caso también nos recuerda la importancia de la cultura de ingeniería: el comentario 'así una notificación mala no envenena todo el lote' refleja una buena intención, pero mal implementada. La solución correcta para evitar que un mensaje problemático afecte a otros es usar políticas de batch con tamaño reducido, o bien procesar mensajes individualmente, o implementar un patrón de dead-letter por mensaje. En Lambda, cuando se usa un lote, si una invocación falla, todos los mensajes del lote se reintentan; pero si se captura la excepción y se devuelve éxito, se pierden todos. La alternativa es devolver un estado de fallo parcial (por ejemplo, marcando mensajes específicos como fallidos en el batch), pero eso requiere una implementación más cuidadosa.

Este incidente también tiene implicaciones de negocio: 41.000 notificaciones perdidas significan clientes insatisfechos, pérdida de ingresos potenciales y daño a la reputación. En entornos SaaS, la entrega de notificaciones es un componente crítico del producto. Por eso, en Q2BSTUDIO integramos sistemas de BI y Power BI para monitorear KPIs de entrega, y usamos IA para detectar anomalías en patrones de notificaciones. Además, la ciberseguridad juega un rol: un fallo en la autenticación de credenciales de email podría exponer datos sensibles si no se maneja correctamente.

La lección final es clara: en sistemas asíncronos, el manejo de errores no es un detalle menor; es el corazón de la fiabilidad. Nunca des por sentado que un try/catch genérico es seguro. Siempre diseña con la DLQ como red de seguridad y monitorea activamente. Y, sobre todo, cuando introduzcas cambios, no confíes solo en que los tests pasan; verifica que los caminos de error funcionan como esperas.

En Q2BSTUDIO ayudamos a empresas a construir aplicaciones a medida con arquitecturas cloud robustas. Nuestros equipos combinan experiencia en AWS, Azure, ciberseguridad, inteligencia artificial y automatización para evitar incidentes como este. Si quieres que tus sistemas sean resilientes, contáctanos.

Resumiendo, la respuesta correcta es la opción B. Los 41.000 mensajes se eliminaron porque cada excepción fue capturada y el handler devolvió éxito, haciendo que Lambda llamara a DeleteMessage. La cola nunca mostró errores porque Lambda reportó invocaciones exitosas. La DLQ permaneció vacía porque ningún mensaje fue reintentado. Un caso clásico de 'excepción tragada' que todos los arquitectos cloud deben conocer.

¿UNA PAUSA?

Juega un momento antes de irte

NUESTROS SERVICIOS

Cómo podemos ayudarte

¿Tienes un proyecto en mente?

Cuéntanos tu visión y la convertimos en una solución de software. Sea cual sea el alcance, hacemos realidad tu idea.