Saltar al contenido principal

Manejo de estados y errores

La API responde los errores con un sobre (envelope) JSON uniforme. Programar contra ese sobre te evita parsear HTML o adivinar.

Manejo de estados y errores: el sobre uniformeGuion: .docx · .yaml

El sobre de error

{ "success": false, "message": "<texto legible>", "code": "<CÓDIGO>" }
  • success — siempre false en un error.
  • message — texto para diagnosticar (no lo muestres tal cual al usuario final).
  • code — código estable para ramificar tu lógica.

Códigos por escenario

HTTPcodeCuándoQué hacer
400VALIDATIONEl cuerpo no cumple el contrato (falta un campo, tipo inválido)Corrige el payload; revisa los campos obligatorios
401UNAUTHENTICATEDFalta el Authorization: Bearer o el token es inválidoReautentica; revisa el header
404NOT_FOUNDEl recurso no existe o no es tuyoNo expongas que existe; trata como no encontrado
409CONFLICTEl recurso existe y choca: un email ya registrado, una operación que no cabe en el estado actualNo reintentes igual. Reintentar un 409 da otro 409
422VALIDATIONEl cuerpo está bien formado pero el objeto que referencia no valeRevisa los identificadores que enviaste, no el formato
429RATE_LIMITEDSuperaste el límite de peticiones por minutoEspera y reintenta con backoff, guiándote por Retry-After. Mira las cabeceras X-RateLimit-* si vienen. Puedes ensayarlo: enciende el freno para tu cuenta desde Credenciales, en el simulador
500Algo se rompió del lado del servidorReintenta con backoff. Si persiste, no es tuyo

Aislamiento por cuenta: consultar una sesión de otra cuenta devuelve 404 (no 403): nunca revelamos la existencia de recursos ajenos.

De dónde sale cada fila

400, 401, 404 y 409 están verificados contra el simulador. 422 y 429 los declara el contrato de SPIDI para las operaciones de Paradas y no los hemos provocado; el 500 es genérico. La diferencia importa: los cuatro primeros puedes reproducirlos hoy, los otros están aquí para que tu manejador no se caiga si llegan.

Ejemplos (verificados contra el simulador)

# sin Bearer en una ruta protegida -> 401 UNAUTHENTICATED
curl https://sim-productos.abiertolab.com/api/v1/ext/payment-sessions/status/ses_xxxxx

# cuerpo inválido (con Bearer) -> 400 VALIDATION
curl -X POST https://sim-productos.abiertolab.com/api/v1/ext/agreements \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{"no":"es-un-agreement"}'

Orden validación → auth: en un POST, la validación del cuerpo corre antes que la autenticación. Un cuerpo inválido sin Bearer devuelve 400 VALIDATION (no 401); para ver el 401 usa una ruta protegida sin cuerpo (como el GET de arriba) o un cuerpo válido sin Authorization.

Estos sobres (401 UNAUTHENTICATED, 400 VALIDATION, 404 NOT_FOUND) están verificados sobre HTTP en simulador/test/func/http-roundtrip.func.test.ts.

Sobre los estados de la sesión

No confundas error (la llamada falló) con estado (pending/paid/failed/expired): un paid o un expired son respuestas exitosas que describen el desenlace. → Ciclo de vida · Estados y contrato de error.