Erros normalizados
Cada SDK levanta exceções diferentes. A jangada traduz tudo para uma hierarquia
única via errors.classify(), com status_code quando disponível. Nenhum erro
nativo de SDK escapa da fronteira dos adapters.
from jangada_ai import LLM, errors
try:
LLM("openai", "modelo-inexistente").complete("oi")
except errors.NotFoundError as e:
print(e.status_code) # 404
except errors.LLMError as e:
print("falha genérica:", e)Hierarquia (resumo)
Todas herdam de errors.LLMError. As principais categorias:
| Erro | Origem típica | Failover padrão? |
|---|---|---|
RateLimitError | 429 | sim |
TimeoutError | timeout de rede | sim |
ConnectionError | falha de conexão | sim |
ServerError | 5xx | sim |
NotFoundError | 404 (modelo/endpoint) | sim (sem retry) |
OutputValidationError | parse() com JSON fora do schema | sim (sem retry) |
AuthError | 401/403 | não |
BadRequestError | 400 (params inválidos) | não |
Conjuntos usados pela política
errors.TRANSIENT— o que dispara retry com backoff (rate limit, timeout, conexão, 5xx).errors.DEFAULT_FAILOVER— o que dispara fallback (os transitórios + 404 +OutputValidationError). Não incluiauthnembad_requestpor padrão.
Você pode customizar retry_on= e backoff_on= por LLM — veja
Retry e fallback.
O que mudou na 1.9.0
- Mais status HTTP mapeados: 408 →
APITimeoutErrore 409 →ServerError(ambos transitórios, entram no retry); 413 →BadRequestError. - Recusas e respostas vazias viram erro normalizado. Resposta sem
choices, recusa da OpenAI noparse(parsed=None) ou Claude semtool_usenoparselevantamOutputValidationError/ServerError— que entram no failover — em vez deIndexError/StopIterationcrus. - Saída cortada no
parseda OpenAI (LengthFinishReasonError) viraTruncatedError, com a dica de aumentarmax_tokens. - Gemini com prompt bloqueado por safety levanta
BadRequestError(sem retry nem fallback — é determinístico), em vez de umServerError"transitório". classify(e, provider, *, request=False): comrequest=True, umValidationErrordo Pydantic vindo da montagem da requisição (SDKs como google-genai e mistralai validam o request) viraBadRequestError, nãoOutputValidationError— não dispara mais failover para outro modelo por umextra=inválido. Os adapters já usam isso nos caminhos que não sãoparse.