Erros
Os erros são em JSON, como todo o resto, com um status HTTP correspondente e um código que você pode usar num switch. A mensagem é uma frase destinada aos seus logs, não aos seus usuários; o texto dela pode mudar, o código nunca.
O envelope de erro
{
"status": "error",
"error": {
"code": "invalid_request",
"message": "Parameter 'lat' must be a number between -90 and 90.",
"param": "lat"
}
}param aparece quando um parâmetro específico causou o problema. X-Request-Id também é definido nas respostas de erro; inclua-o se entrar em contato com o suporte.
Códigos
| HTTP | code | Quando | O que fazer |
|---|---|---|---|
| 400 | invalid_request | Falta um parâmetro obrigatório, um valor está malformado ou fora do intervalo, há mais de 100 pontos ou endereços num lote, foram pedidos mais de 10 resultados. | Corrija a requisição. Não tente de novo sem alterações. |
| 401 | missing_key | Nenhuma chave foi enviada e o acesso sem chave está desativado neste servidor. Por padrão ele fica ativado, e uma requisição sem chave é simplesmente respondida. | Envie uma chave como X-API-Key, um token bearer ou key=. |
| 429 | quota_exceeded | O endereço já usou as suas 2.500 requisições gratuitas do dia sem chave. | Aguarde o reinício (Retry-After e X-Quota-Reset dizem quando) ou envie uma chave que tenha crédito ou um pacote Unlimited. |
| 401 | invalid_key | A chave não existe. | Verifique se há erros de digitação ou uma cópia incompleta. |
| 401 | key_revoked | A chave foi revogada no painel. | Use uma chave válida. |
| 402 | no_credits | A cota gratuita do dia da chave foi usada e o saldo de crédito da conta está zerado. | Adicione crédito no painel, com cartão ou criptomoeda, ou aguarde o reinício. |
| 403 | key_ip_limit | Todas as vagas de IP desta chave estão ocupadas por outros endereços por enquanto. | Use uma das máquinas que ocupam as vagas, dê a esta máquina uma chave própria ou adicione um pacote. Veja vagas de IP. |
| 403 | account_suspended | A conta está suspensa. | Verifique o e-mail que enviamos ou abra um chamado. |
| 404 | not_found | O caminho não existe. Uma consulta sem correspondências retorna 200 com resultados vazios, não 404. | Verifique o caminho e o prefixo de versão. |
| 500 | server_error | Algo quebrou do nosso lado. | Tente de novo uma vez depois de um segundo. O erro é registrado e nos alerta. Não é contado. |
| 503 | unavailable | Um backend está temporariamente indisponível. | Tente de novo com backoff. Não é contado. |
Coisas que não são erros
- Nenhum resultado. Uma geocodificação direta de um texto sem sentido retorna
200com"results": []. Uma geocodificação reversa no oceano retorna200com"result": null. Ambas contam como uma requisição. - Baixa precisão. Um resultado com
"precision": "admin"quando você queria uma casa é uma requisição bem-sucedida que encontrou menos do que você esperava. Verifique o campo. - Endereços IP privados. Consultar
10.0.0.1retorna200com"is_private": truee sem localização.
Erros nos hosts compatíveis
Os hosts de compatibilidade retornam erros no formato que o provedor original usa, então o tratamento existente funciona. Por exemplo, um saldo de crédito zerado é "status": "OVER_QUERY_LIMIT" com HTTP 200 em gapi.mygeocode.com, "statusCode": 429 no envelope do Bing em bing.mygeocode.com e {"status":"fail","message":"quota"} em ipapi.mygeocode.com; uma chave inválida é REQUEST_DENIED, 401 e invalid key, respectivamente. Os cabeçalhos X-Quota-* são enviados em todos os hosts de qualquer forma, então você pode ler o estado real nos cabeçalhos se quiser.
Uma estratégia de tratamento razoável
def call(url, params, tries=3):
for attempt in range(tries):
r = session.get(url, params=params, timeout=10)
if r.status_code == 200:
return r.json()
body = r.json()
code = body["error"]["code"]
if r.status_code in (500, 503):
time.sleep(0.2 * (2 ** attempt))
continue
# no_credits, key_ip_limit, invalid_request, invalid_key: retrying will not help
raise ApiError(code, body["error"]["message"], r.headers.get("X-Request-Id"))
raise ApiError("retries_exhausted", "Gave up after %d attempts" % tries, None)