Árbol del API · Guías › Errores y reintentos
Errores y reintentos
errors[]
Dónde llegan los errores, qué significa cada código y cuándo reintentar sin duplicar registros.
Un error puede llegar en tres lugares. Revisa los tres en cada respuesta.
1. El estatus HTTP
| Estatus | Cuándo | Qué hacer |
|---|---|---|
| HTTP 401 | Falta el header Authorization, la llave no existe o es de otra empresa. No trae cuerpo. |
Revisa la llave y el subdominio. No reintentes. |
| HTTP 403 | La cuenta de la empresa está desactivada. El cuerpo es el texto «Cuenta desactivada». | Habla con el administrador de la empresa. |
| HTTP 422 | La llave no tiene el permiso de una mutación o de ciertas consultas (cada operación lo indica), un dato fue rechazado al guardar, o hubo una falla interna. El cuerpo es {"error": "invalid_graphql_request"} o {"error": "<mensaje>"}, sin data. |
Revisa los permisos de la llave y los datos. Si no cambiaste nada, reintenta con espera (en mutaciones, con la misma idempotencyKey). |
| HTTP 5xx | Falla del servicio o de la red. | Reintenta con espera exponencial. |
Para todo lo demás el API responde HTTP 200, aunque la operación haya
fallado: el detalle va en el cuerpo. Con Llave API no existe el código
INTERNAL: una falla interna llega como HTTP 422.
2. errors de la respuesta
Los errores de la consulta llegan en errors, con su código en
extensions.code:
{
"errors": [
{
"message": "Order not found",
"path": ["order"],
"extensions": { "code": "NOT_FOUND" }
}
],
"data": { "order": null }
}| Código | Significado | ¿Reintentar? |
|---|---|---|
NOT_FOUND |
No existe el registro pedido en la empresa. | No |
VALIDATION |
Un dato no es válido; extensions.field puede decir cuál. |
No, corrige el dato |
INACTIVE |
El registro existe pero ya no se ofrece (un almacén o un tipo de venta inactivo). | No, elige otro |
CONFLICT |
El estado del registro impide la operación, o el registro estaba bloqueado por otra operación. | Sólo si es un bloqueo, con espera |
FORBIDDEN |
La llave no tiene un permiso adicional que pide la operación. | No, revisa la llave |
Si la consulta está mal escrita (un campo que no existe, un argumento con un
valor del tipo equivocado), no hay data y extensions.code trae el código
del validador de GraphQL, como undefinedField o
argumentLiteralsIncompatible. Si el valor equivocado viene en una
variable, el error trae extensions.problems y puede no traer code.
Corrige la consulta; reintentar no ayuda.
3. errors dentro de una mutación
Las mutaciones devuelven además sus propios errors, con el dato que causó
cada uno. Pídelos siempre:
mutation CrearOrden($input: OrderInput!, $clave: String!) {
createOrder(input: $input, idempotencyKey: $clave) {
order { id folio }
errors { field code message }
}
}Con errores, order llega null. field señala el dato, por ejemplo
lines[1].quantity para la segunda partida de una orden o
applications.0.invoiceId para la primera factura de un cobro (se cuentan
desde 0). Un error de una mutación también puede llegar en errors de la
respuesta: revisa los dos.
Una llave sin el permiso de una consulta no siempre recibe un error: casi todas las listas llegan vacías y los detalles llegan
null, sinerrors, y la lista de clientes también lleganull. Las listas de estructuras de precios y de precios de una lista no admitennull: respondendata: nullcon un error sinextensions.code(«Cannot return null for non-nullable field…»). El API conserva esas respuestas para las integraciones que ya las usan. Cada operación de la referencia dice qué pasa sin su permiso.
Reintentos sin duplicar
Las mutaciones que registran algo piden una idempotencyKey: una clave
única que generas tú por cada operación de negocio (un UUID, o el folio del
pedido en tu sistema).
- Si repites la petición con la misma clave y los mismos datos, no se registra nada de nuevo: recibes el registro que se creó la primera vez, como está en ese momento. Así puedes reintentar con seguridad después de un corte de red, un HTTP 5xx o un HTTP 422 inesperado.
- Si usas la misma clave con otros datos, recibes
CONFLICT. - La clave se recuerda alrededor de 30 días; una tarea diaria borra las más antiguas.
Las consultas no cambian nada y se pueden repetir siempre. Reintenta con espera exponencial (por ejemplo 1, 2, 4 y 8 segundos) y un límite de intentos.