tecsas3-cli usa exit codes estables para que los orquestadores (systemd, GitHub Actions, Airflow, cron, scripts bash) puedan enrutar errores sin parsear stderr. Cada subclase de TecsaError define su propio exit_code y el handler central en cli/src/tecsas3_cli/cli.py:run() los traduce a sys.exit(...).
El rango 0–5 se reserva para clases de error conocidas y predecibles; el 99 absorbe cualquier excepción no esperada.
Tabla de exit codes
La asignación anterior es la implementada en
cli/src/tecsas3_cli/errors.py y en el handler run() de cli/src/tecsas3_cli/cli.py. Los códigos 0 y 1 son los únicos compartidos por varias clases: NotFoundError y ValidationError colapsan a 1 para simplificar el branching en shell (if ! tecsas3 ...; then ...).Mapeo desde HTTP status
El factoryfrom_http_status(status, message, ...) centraliza la conversión. Cualquier 4xx/5xx que llegue del backend se traduce a la subclase apropiada y conserva http_status, hint y request_id para diagnóstico.
Ejemplos por exit code
Patrones de scripting
Branching simple por éxito / fallo
Reintentos sólo en ServerError (exit 2)
Enrutamiento por tipo de error en CI
Inspección del error completo
Con--json, los errores se serializan con todos los campos de diagnóstico:
request_id aparece cuando el backend lo emite en X-Request-ID y permite correlación con los logs del servidor.
Troubleshooting
Exit code inesperado en pipes
pipefail o usa:
Exit 2 persistente tras reintentos
ServerError ya incluye 2 reintentos con backoff 0.5s/1s. Si el backend sigue 5xx tras 3 intentos totales, el CLI emite exit 2. Posibles causas:
- Caída real del servicio — revisa el dashboard de salud del tenant.
- Mantenimiento programado — espera la ventana y reintenta más tarde.
- Bug reproducible — captura el
request_idy repórtalo a soporte.
Exit 3 (AuthError) inmediato tras login
El login fue OK pero el siguiente comando falla con 401. Causa típica: el backend invalida tokens emitidos con un SECRET_KEY distinto al actual (rotación de claves o reinicio de entorno). Solución:
Exit 4 (ConfigError) con TOML válido
load_settings ignora silenciosamente secciones [profile.<x>] que no parsean. Verifica que el perfil que estás invocando existe:
Exit 5 (NetworkError) sólo en CI
El runner no tiene acceso al backend (firewall corporativo, NAT, DNS privado). Diagnóstico:
Exit 99 con stacktrace verboso
El handlerrun() imprime code=UNEXPECTED y la excepción cruda a stderr. Para reportarlo:
Siguientes pasos
- Profundiza en la redacción PHI que se aplica a
stderren modo--debug. - Aprende a fijar el formato de salida por defecto.
- Revisa la configuración para validar
base_urly tenant antes de correr scripts largos.