Errores legibles en una API de multas: cómo escribir el mensaje
“Error inesperado” obliga a abrir el código para saber qué pasó. Un mensaje sirve cuando dice qué se rechazó, sobre qué parte del pedido y qué puede hacer quien lo lee.
Un ticket de soporte llega con una captura y una frase: “Error inesperado al procesar la solicitud”. Nadie puede decidir nada con eso. Quien integró la API no sabe si el pedido estaba mal armado, si la credencial venció o si una jurisdicción no respondió; quien atiende el ticket tampoco.
El cuerpo de un error se escribe una vez y se lee en el peor momento: cuando una flota no sabe si tiene multas o si la consulta falló. Un error es legible cuando quien lo recibe puede elegir el paso siguiente sin abrir el código del servidor.
RFC 9110 pide que, ante un error del cliente o del servidor, la respuesta incluya una representación que explique la situación y si la condición es temporal o permanente. El número de tres dígitos no lo dice; el cuerpo sí, y sólo si alguien se sentó a escribirlo.
Dos lectores en la misma respuesta
Un error tiene dos destinatarios con necesidades opuestas: el programa que carga las actas necesita una llave estable; la persona, prosa. RFC 9457 reparte los roles en un mismo documento —el inventario de miembros lo ordena la nota sobre códigos de estado— y establece la jerarquía: el consumidor debe tomar el tipo como identificador primario y no debería sacar información del miembro escrito para personas, porque para eso están las extensiones.
Eso libera la redacción: si el cliente no lee la prosa para decidir, la prosa puede reescribirse o traducirse sin romper una integración, siempre que el tipo no cambie. El tipo es además la llave con la que se decide qué repetir, criterio de la nota sobre errores que conviene reintentar y errores que no.
Omitir el tipo tampoco es neutral. La especificación registra un tipo por defecto, about:blank, con un significado preciso: el problema no agrega nada al código HTTP. Un error sin tipo declara, formalmente, que no hay más para decir.
Qué tiene que responder el texto
Un detalle útil contesta tres preguntas en el orden en que las hace quien lo lee:
- qué se rechazó, en términos del pedido y no de la implementación;
- sobre qué parte del pedido, con el campo o el elemento identificado;
- qué puede hacer ahora quien recibe el mensaje.
RFC 9457 apunta ahí: pide que el detalle ayude a corregir el problema en lugar de entregar información de depuración. “Validación fallida” no responde ninguna de las tres. “La patente del elemento 12 del lote no corresponde a ningún formato vigente; corregila y reenviá sólo ese elemento” responde las tres.
El título es otro texto y otra tarea: nombra la clase —“patente inválida”, “jurisdicción sin respuesta”—, no el caso, y la especificación pide que no cambie entre ocurrencias salvo por traducción. Si hay que reescribirlo cada vez que cambia el caso, lo mal recortado era la clase.
Cuando el dato que hace falta es estructurado —qué campo, qué jurisdicción falló, cuántos segundos esperar— va en un miembro de extensión, no adentro de la frase: un cliente puede leer un valor, no aplicarle una expresión regular a una oración ajena.
Lo que no entra en el mensaje
RFC 9457 pide revisar con cuidado qué información entra en un tipo de problema y qué se genera en cada ocurrencia: el riesgo es filtrar algo que comprometa el sistema o la privacidad de sus usuarios, y desaconseja en particular exponer volcados de pila por la interfaz HTTP. La lista corta de lo que no debería viajar en el texto:
- la patente, el CUIT o el nombre de la persona consultada;
- credenciales, tokens o fragmentos de la solicitud autenticada;
- rastros de pila, consultas a la base o nombres de host internos;
- el proveedor aguas arriba, cuando nombrarlo revela más de lo que ayuda.
Nada de eso mejora la decisión siguiente y un texto de error viaja lejos del perímetro donde nació; el mismo criterio vale para lo que se mide alrededor, como vemos en trazas y métricas sin patentes ni CUIT.
Sacar el detalle interno, eso sí, deja a soporte sin hilo para volver al caso. RFC 9457 prevé una referencia a la ocurrencia concreta y W3C Trace Context define un identificador que sigue una misma traza entre servicios, con la prohibición de usar esos campos para información personal o sensible. Con los dos alcanza: quien reporta pega un identificador corto y quien atiende recupera el resto del lado del servidor.
Escribirlos como catálogo, no de a uno
Los mensajes rinden cuando se escriben juntos y no cuando aparece una excepción nueva: un tipo por clase de problema, con su título, su redacción y la acción sugerida, revisado como cualquier texto que ve una flota. Ese catálogo necesita dueño; si nadie lo edita, cada mensaje queda redactado por quien escribió el catch.
La documentación puede sostenerlo: OpenAPI permite adjuntar ejemplos a cada respuesta, así que el texto exacto deja de vivir sólo en el código. Y como RFC 9457 obliga al consumidor a ignorar las extensiones que no reconoce, el catálogo puede crecer sin romper a quien lo consume hoy. Un tipo que aparece en producción y no figura ahí es una fila que falta.
La prueba de calidad es barata: leé cada texto sin contexto, como alguien a las tres de la mañana, y preguntá qué haría a continuación. Si la respuesta es “abrir el código”, el mensaje todavía no está escrito.
Después revisá el catálogo con tres preguntas: si algún error puede confundirse con “esta patente no tiene multas”; si cada tipo ofrece una acción y no sólo un diagnóstico; y si algún mensaje lleva un dato que no quisieras ver pegado en un ticket.
Metodología
- Alcance
- Redacción y estructura del cuerpo de una respuesta de error en una API de consulta de infracciones. No cubre la elección del código de estado ni la clasificación de causas para reintentar, que tienen notas propias.
- Unidad de análisis
- Un mensaje de error individual, tomado como tipo, título, detalle y acción que habilita en quien lo lee.
- Cobertura
- Lo dicho sobre el formato, el rol de cada miembro y la documentación por operación proviene de las especificaciones citadas. No describe cómo redacta sus errores un proveedor o un portal oficial en particular.
Limitaciones
- RFC 9457 advierte que un intermediario —un proxy, una caché, un balanceador— puede alterar en tránsito lo que el servicio respondió; el error que llega al cliente no siempre es el que se escribió.
- Un texto claro no reemplaza la clasificación de causas: un mensaje bien redactado puede describir una falla que igual conviene reintentar.
- Qué dato resulta sensible depende del contexto de cada integración y debe revisarse con quien administra esos datos.
Fuentes
- RFC 9457 — Problem Details for HTTP APIs — RFC Editor (consultada el )
- RFC 9110 — HTTP Semantics — RFC Editor (consultada el )
- W3C Trace Context — World Wide Web Consortium (consultada el )
- OpenAPI Specification version 3.1.2 — OpenAPI Initiative (consultada el )
Preguntas frecuentes
¿El cliente puede decidir a partir del texto del error?
No conviene. RFC 9457 pide usar el tipo del problema como identificador primario y desaconseja que el consumidor extraiga información del miembro escrito para personas, porque para eso están las extensiones. Además el título puede traducirse según el idioma que negocie el cliente, así que una integración que compara oraciones se rompe el día que alguien pide otra lengua.
¿Qué diferencia hay entre el título y el detalle de un error?
El título nombra la clase de problema y, según la especificación, no debería cambiar entre ocurrencias salvo por traducción. El detalle habla del caso concreto y debería orientarse a ayudar a corregirlo antes que a entregar información de depuración. Un caso límite: cuando el problema no agrega nada al código HTTP, la especificación sugiere que el título repita la frase del propio código.
¿Conviene incluir la patente consultada en el mensaje de error?
No. El texto de un error termina en logs, tableros, tickets y capturas de pantalla, muchas veces fuera del sistema que lo generó, y RFC 9457 pide examinar con cuidado qué se expone en cada ocurrencia. Para volver al caso alcanza con una referencia a la ocurrencia y un identificador de traza, sin arrastrar el dato consultado.
¿Alcanza con el código HTTP para explicar una falla?
No. RFC 9110 pide que ante un error del cliente o del servidor la respuesta incluya una representación que explique la situación y si la condición es temporal o permanente, con la excepción de las respuestas a un HEAD. Es una recomendación y no una obligación: hay servicios que devuelven tres dígitos y nada más, y esos tres dígitos no dicen qué campo se rechazó ni qué fuente no respondió.
Notas relacionadas
Códigos de estado: qué significa cada uno en la práctica
Un 200 no dice que el vehículo esté sin deuda y un 404 no dice que el dominio no exista. El número califica la solicitud; el resultado de la consulta vive en el cuerpo.
Errores de la API de multas que conviene reintentar y cuáles no
Repetir una solicitud sólo ayuda cuando la causa del error puede desaparecer sola. Clasificar por causa, y no por código de estado, define qué se reintenta, qué espera una acción y qué se cierra.
Entrega garantizada: qué pasa si el aviso de una multa falla
Un evento que no se pudo entregar no debería desaparecer: entra en reintentos con calendario, retención con plazo y una vía de reenvío. Qué compromisos hacen verificable la garantía.