Tratamento de Erros
Códigos de erro, estratégias de retry e recuperação de falhas
Este guia cobre cenários comuns de erro e como tratá-los na sua integração de canal.
Códigos de status HTTP
| Code | Significado | Ação |
|---|---|---|
200 | Sucesso | Processar a resposta |
201 | Criado | Recurso criado com sucesso |
400 | Requisição inválida | Verifique o corpo da requisição — tipo de conteúdo inválido, sessão não aberta, etc. |
401 | Não autorizado | Verifique seu token de API |
404 | Não encontrado | Sessão ou mensagem não existe |
422 | Erro de validação | O corpo da requisição falhou na validação — verifique tipos e valores dos campos |
Respostas de erro comuns
401 Unauthorized
{
"detail": "Invalid or expired token"
}Verifique se o header Authorization: Bearer sk_live_... está definido corretamente e se o token não expirou.
404 Not Found
{
"detail": "Session not found"
}O ID da sessão não existe ou pertence a uma organização diferente.
400 Bad Request — Sessão não aberta
{
"detail": "Session is not open"
}Você está tentando responder ou criar mensagens em uma sessão fechada. Crie uma nova sessão.
400 Bad Request — Sem agente de IA
{
"detail": "Session has no agent"
}A sessão não tem um agente atribuído. Atribua um via POST /sessions/{id}/transfer ou crie uma nova sessão com agent_id.
422 Validation Error
{
"detail": [
{
"loc": ["body", "content", "type"],
"msg": "value is not a valid enumeration member",
"type": "type_error.enum"
}
]
}O corpo da requisição não corresponde ao schema esperado. Verifique os nomes dos campos, tipos e valores permitidos.
Estratégia de retry
Quando fazer retry
- Erros 5xx — problemas no servidor, faça retry com backoff exponencial
- 429 Too Many Requests — rate limited, faça retry após o delay indicado
- Erros de rede — problemas transitórios de conectividade
Quando NÃO fazer retry
- Erros 4xx (exceto 429) — erros do cliente que não serão resolvidos com retry
- Falhas na entrega de mensagens — reporte o status de falha em vez de tentar novamente
Exemplo de backoff exponencial
import asyncio
import httpx
async def api_call_with_retry(method: str, url: str, max_retries: int = 3, **kwargs):
for attempt in range(max_retries):
try:
response = httpx.request(method, url, headers=HEADERS, **kwargs)
if response.status_code < 500:
return response
except httpx.TransportError:
pass
if attempt < max_retries - 1:
await asyncio.sleep(2 ** attempt) # 1s, 2s, 4s
raise Exception(f"API call failed after {max_retries} retries")Tratamento de condições de corrida
Status de entrega antes da criação da mensagem
Confirmações de entrega do seu canal podem chegar antes da Antonnia finalizar a criação da mensagem. Se você não encontrar a mensagem pelo provider_message_id, isso é esperado — registre no log e ignore:
messages = httpx.post(
f"{BASE_URL}/sessions/{session_id}/messages/search",
headers=HEADERS,
json={"provider_message_id": channel_msg_id},
).json()
if not messages:
logger.info("Message not yet created, skipping status update",
provider_message_id=channel_msg_id)
returnCriação duplicada de sessões
Sem locking, mensagens simultâneas do mesmo contato podem criar sessões duplicadas. Sempre use um lock distribuído ao redor do get-or-create de sessão:
async with redis_lock(f"lock:mychannel:{contact_id}:{instance_id}", timeout=30):
session = await get_or_create_session(contact_id, instance_id)Tratamento de erros específicos do canal
Falhas no download de mídia
Se o download de mídia do seu canal falhar, use um placeholder de texto como fallback:
try:
media_url = await download_and_host(channel_media_url)
content = {"type": "image", "url": media_url}
except Exception:
content = {"type": "text", "text": "[Image could not be loaded]"}Erros na API do canal
Quando a API de envio do seu canal falhar, reporte a falha para a Antonnia:
try:
channel_msg_id = await channel_api.send(instance_id, user_id, content)
await update_delivery_status(message_id, "sent", channel_msg_id)
except ChannelAPIError as e:
await update_delivery_status(
message_id, "failed",
error_code=e.code,
error_message=str(e),
)Logging estruturado com contexto (session_id, message_id, detalhes do erro) torna muito mais fácil debugar problemas em produção. Use nível warning para erros esperados e nível exception para erros inesperados.