1 min de lectura

Los errores son parte del producto

Un fallo sobre el que el usuario puede actuar es una funcionalidad. Cómo este boilerplate nombra los errores de dominio una sola vez y los mapea a todas las puertas — tRPC, Server Actions, REST y los textos.

ingenieríaarquitectura

La mayoría de los proyectos tratan los errores como humo: algo salió mal, lanza un string, ojalá lo capture algún boundary. Este boilerplate trata un fallo sobre el que el usuario puede actuar como parte de la superficie del producto, con el mismo rigor que un camino feliz.

Nombra el fallo una sola vez

Cada fallo de negocio recibe un código estable — credits/insufficient, note/not-found — acuñado por la fábrica de errores de su feature. La clase es privada; el código es el contrato.

throw creditsErrors.insufficient({ required: 3, available: 1 })

Quien lo consume se ramifica por el código, nunca por instanceof. Los códigos sobreviven a la serialización en cualquier transporte; la identidad de clase no.

El registro obliga a ser exhaustivo

Un código nuevo no compila hasta que está mapeado en todos los sitios donde un usuario podría encontrárselo: un estado HTTP, un error de tRPC y el texto del diccionario en cada idioma. Olvidarse de la traducción al español es un error de compilación, no un ticket de soporte.

Las puertas traducen, no deciden

Una Server Action, un procedimiento de tRPC y un handler REST exponen todos el mismo credits/insufficient, cada uno en el dialecto nativo de su transporte. La decisión de que no había créditos suficientes se tomó una vez, en el modelo.

Los errores inesperados se quedan genéricos

Cualquier cosa sin código registrado se sanea a un mensaje genérico. Los detalles van a los logs y al error tracking; los stack traces nunca salen por el cable.

La recompensa

Cuando producto pregunta "¿qué puede salir mal realmente en el checkout?", el registro de errores responde con solo leerlo. Esa lista es la especificación honesta de la funcionalidad — y salió gratis.