Saltar al contenido

Diseñar los códigos de error

Treinta cadenas en mayúsculas no son un sistema. Las tres reglas que hacen que un catálogo de códigos sirva, la granularidad correcta, y por qué el criterio es qué hace el frontend y no qué pasó en el core.

El criterio

Aplicado, el resultado sorprende: la mayoría de los fallos internos comparten un solo código. Un error de serialización, un cerrojo envenenado, una invariante rota — el usuario no puede hacer nada con ninguno y el frontend hace lo mismo con los tres: registrar y avisar en genérico. Ese es INTERNO, y no hace falta más.

Las tres reglas de forma

1 · Mayúsculas con guiones bajos, sin acentos y en inglés o en un vocabulario fijo. No es una preferencia estética: es que el código va a aparecer en comparaciones, en claves de traducción y en registros, y cualquier variación de escritura es un fallo silencioso. NO_EXISTE o NOT_FOUND, pero uno de los dos y siempre igual.

2 · Prefijo de dominio cuando el fallo es de un dominio. PROYECTO_BLOQUEADO, CATALOGO_DESACTUALIZADO. Los genéricos van sin prefijo: NO_EXISTE, SIN_PERMISO, RED, INTERNO. Así se lee de un vistazo si un fallo es de tu dominio o del sistema.

3 · Sin números ni jerarquías. E1042 no dice nada y obliga a mantener una tabla; PROYECTO_BLOQUEADO se lee. Y las jerarquías con puntos —proyecto.carga.bloqueado— prometen una estructura que después nadie respeta.

El catálogo típico

Siete códigos genéricos más los de dominio suelen bastar para una aplicación entera. Si tu catálogo pasa de veinte, la señal es que estás codificando lo que pasó en vez de lo que hay que hacer.

Mantenerlo

La buena noticia del nivel 18.2: el catálogo se mantiene solo. El match exhaustivo de la conversión obliga a asignar un código a cada variante nueva, así que no puede haber un fallo sin código.

Lo que sí conviene tener escrito es la lista de códigos con lo que significan, en un sitio que el frontend también use:

Rust
// error.rs — la lista, y es la única documentación que hace faltapub mod codigos {    pub const NO_EXISTE: &str = "NO_EXISTE";    pub const SIN_PERMISO: &str = "SIN_PERMISO";    pub const EN_USO: &str = "EN_USO";    pub const RED: &str = "RED";    pub const INTERNO: &str = "INTERNO";    pub const PROYECTO_BLOQUEADO: &str = "PROYECTO_BLOQUEADO";}

Usar constantes en vez de cadenas sueltas hace dos cosas: un error de escritura en el core no compila, y el conjunto de códigos es una lista que se puede leer. Con bindings generados —nivel 19— esa lista puede llegar también al frontend, y entonces la comparación de códigos deja de ser texto libre en los dos lados.