//Como usar

Erros do Jev: 401, 422, 429 e 529 na prática

Dois desses códigos você repete; dois você conserta. Confundir os grupos é a forma mais rápida de transformar um erro de digitação em uma tempestade de requisições.

Erro de API divide-se em dois grupos, e tratar os dois do mesmo jeito é o erro de integração mais comum que existe. Um grupo é culpa do seu código, e repetir não adianta nada. O outro é transitório, e repetir é exatamente o certo — com backoff.

A referência oficial do Jev documenta quatro códigos, e os SDKs mapeiam alguns outros.

A tabela dos quatro

CódigoSignificado oficialRepetir?
401 Unauthorizedchave ausente ou inválida; confira o cabeçalho Authorizationnão
422 Unprocessable Entityo corpo reprovou na validação; a resposta detalha o camponão, sem mudar o corpo
429 Too Many Requestslimite de taxa excedidosim, com backoff
529 Overloadeda TypeSafe está temporariamente sobrecarregadasim, com backoff

Guarde a divisão: 401 e 422 você conserta; 429 e 529 você espera.

401: a chave

Quase sempre é uma destas três coisas: a variável de ambiente não chegou ao processo, a chave foi copiada com espaço no fim, ou o cabeçalho está montado sem o prefixo Bearer . A forma correta é Authorization: Bearer <chave>.

Um detalhe do SDK que evita confusão: a documentação de configuração diz que valores de ambiente vazios ou só com espaço em branco são ignorados. Ou seja, uma variável definida como string vazia se comporta como variável ausente, e o erro é o mesmo.

Nunca repita um 401 em laço. A chave não vai melhorar sozinha.

422: o corpo

Este é o código que mais aparece no primeiro dia e o que mais gente trata errado. Ele significa que o servidor validou a requisição e recusou, e a resposta diz qual campo está errado. Leia o corpo do erro antes de qualquer outra coisa.

As causas mais comuns têm a ver com a forma das perguntas:

  • criteria de Score que não é uma lista ordenada, ou tem menos de dois níveis;
  • criteria de Choice enviado como lista em vez de mapa de opção para descrição;
  • type ausente ou escrito diferente de noul, choice ou score;
  • questions vazio;
  • model com um nome que a sua conta não pode enviar.

No SDK de JavaScript, parte dessas validações acontece antes da rede: a documentação do systemOne diz que ele lança quando as perguntas estão vazias ou quando o criteria de Score não é uma lista de pelo menos duas entradas. É melhor assim — falha local é mais rápida e mais barata que 422.

O que não fazer: colocar o 422 na mesma política de retentativa do 429. Um corpo inválido continua inválido na décima tentativa, e você transformou um erro de digitação em uma rajada de requisições.

429: o limite de taxa

Significa que você passou de um dos limites publicados. Não é um erro do corpo, é um pedido para desacelerar.

A referência recomenda repetir com backoff exponencial em vez de repetir imediatamente, e diz que os SDKs oficiais fazem isso sozinhos com a política padrão. No SDK Python, a exceção TypeSafeRateLimitError expõe retry_after_ms, com o tempo que o servidor pediu — quando o servidor manda um número, obedeça a ele em vez do seu próprio backoff.

Se o 429 é constante e não esporádico, o problema não é de retentativa: é de dimensionamento. Veja limites de taxa.

529: a sobrecarga

Aqui o erro é do outro lado, e a resposta certa é a mesma do 429: esperar e tentar de novo depois de um intervalo curto. A diferença prática é que 529 não tem relação com o seu volume, então aumentar a espera do seu lado não é punição — é cooperação.

Vale desenhar o sistema supondo que isso acontece. Em um fluxo assíncrono, uma fila com repetição resolve. Em um fluxo síncrono na frente de um usuário, decida antes qual é o comportamento aceitável: esperar, responder com uma decisão padrão ou mandar o caso para uma fila.

As exceções dos SDKs

O SDK Python organiza tudo em uma hierarquia:

ExceçãoQuando
TypeSafeErrorbase de todas as falhas do SDK
TypeSafeAPIErrorresposta HTTP sem sucesso; traz status, body, headers, endereço da requisição e request_id
TypeSafeBadRequestError400
TypeSafeAuthenticationError401
TypeSafePermissionDeniedError403
TypeSafeNotFoundError404
TypeSafeUnprocessableEntityError422
TypeSafeRateLimitError429, com retry_after_ms
TypeSafeInternalServerError5xx
TypeSafeAPIConnectionErrorfalha sem resposta HTTP
TypeSafeAPITimeoutErrortempo limite estourado
TypeSafeAPIResponseValidationErrorresposta bem-sucedida com corpo fora do formato; traz field_path

Duas dessas merecem atenção especial.

request_id vem do cabeçalho x-typesafe-request-id. Registre sempre. É o que permite falar com o suporte sobre uma requisição específica em vez de sobre uma impressão.

TypeSafeAPIResponseValidationError é a mais fácil de ignorar e a mais confusa quando acontece: o HTTP deu certo, e o corpo não trouxe o que era esperado. O field_path aponta o caminho, no formato answers.tone.confidence — o que, aliás, é um lembrete útil de que Noul não devolve confidence, como explicado em probabilidade não é confiança.

Um esqueleto de tratamento

from typesafe_sdk import (
    TypeSafeAuthenticationError,
    TypeSafeRateLimitError,
    TypeSafeUnprocessableEntityError,
    TypeSafeAPIError,
)

try:
    resposta = client.system_one(state=estado, questions=perguntas)
except TypeSafeUnprocessableEntityError as erro:
    # Erro nosso: registrar o campo e NÃO repetir.
    log.error("corpo inválido", extra={"body": erro.body, "req": erro.request_id})
    raise
except TypeSafeAuthenticationError:
    # Erro de configuração: alertar, não repetir.
    raise
except TypeSafeRateLimitError as erro:
    # O SDK já repetiu; se chegou aqui, a fila precisa desacelerar.
    fila.reduzir_paralelismo(espera_ms=erro.retry_after_ms)
    raise
except TypeSafeAPIError as erro:
    log.error("falha da API", extra={"status": erro.status, "req": erro.request_id})
    raise

Um aviso que importa no Brasil

A documentação do SDK Python avisa que, no nível de log debug, cabeçalhos secretos são mascarados mas os corpos de requisição e resposta não são. Se o seu state carrega dado pessoal, deixar debug ligado em produção coloca esse dado no log. Vale checar antes de subir.

Para os padrões de repetição, veja retentativas e tempo limite. Para a chamada crua, a API HTTP sem SDK. O índice está em como usar.

Perguntas frequentes

Quais códigos de erro a API do Jev retorna?

A referência oficial documenta quatro: 401 para chave ausente ou inválida, 422 para corpo reprovado na validação, 429 para limite de taxa excedido e 529 quando a TypeSafe está sobrecarregada. Os SDKs mapeiam também 400, 403, 404 e a faixa 5xx.

Posso repetir um 422?

Não sem mudar o corpo. 422 significa que a requisição foi rejeitada na validação e a resposta indica qual campo está errado. Repetir o mesmo corpo produz exatamente o mesmo 422, consome cota e atrasa o conserto.

Como trato 429 e 529?

Repetindo com backoff exponencial, nunca imediatamente. A referência recomenda isso explicitamente, e os SDKs oficiais já fazem por padrão. Em 429 o SDK Python expõe retry_after_ms, com o tempo que o servidor pediu.

Qual exceção o SDK Python lança em cada caso?

TypeSafeError é a base. TypeSafeAPIError cobre respostas HTTP e traz status, body, headers, endpoint e request_id. Dela descendem TypeSafeBadRequestError (400), TypeSafeAuthenticationError (401), TypeSafePermissionDeniedError (403), TypeSafeNotFoundError (404), TypeSafeUnprocessableEntityError (422), TypeSafeRateLimitError (429) e TypeSafeInternalServerError (5xx).

O que é o request_id e para que serve?

É o cabeçalho x-typesafe-request-id, exposto pela exceção do SDK. Registre-o junto com o erro: é o identificador que permite conversar com o suporte sobre uma requisição específica.

E quando a resposta chega com o formato errado?

O SDK Python lança TypeSafeAPIResponseValidationError, com um field_path apontando o campo, no formato answers.tone.confidence. É uma resposta HTTP bem-sucedida cujo corpo não trouxe o que era esperado.

Quer dominar decisões com IA em português? O curso da comunidade está em pré-venda.

Garantir pré-venda por R$ 499,00

Pré-venda: R$ 499,00 · Após o lançamento: R$ 799,00