Tratamento de erros
Entenda as respostas de erro da API ChartQuery e aprenda a lidar com cada caso corretamente.
Cada solicitação à API ChartQuery retorna um código de status HTTP padrão. Este guia explica o que cada código significa, quando os créditos são consumidos e como lidar com falhas na sua integração.
Formato de resposta
Respostas bem-sucedidas retornam um objeto JSON com os dados do endpoint. Respostas de erro seguem uma estrutura consistente:
{
"error": "Human-readable description of what went wrong"
}Sempre verifique o código de status HTTP antes de ler o corpo.
Códigos de status
200 Sucesso
Cobrado. A solicitação foi concluída com sucesso. Os créditos são deduzidos do seu saldo.
const res = await fetch(url, { headers: { "x-api-key": API_KEY } })
if (res.status === 200) {
const data = await res.json()
// process data
}201 Trabalho criado
Cobrado. Um trabalho assíncrono foi criado e aceito. Os créditos são deduzidos imediatamente quando o trabalho é enfileirado.
202 Aceito (async)
Ainda não cobrado. A solicitação foi aceita e enfileirada. Use o ID do trabalho retornado para consultar o resultado. Os créditos só são cobrados quando o trabalho é concluído com sucesso.
400 Solicitação incorreta
Não cobrado. Sua solicitação contém parâmetros inválidos ou ausentes.
Causas comuns:
- Um parâmetro de consulta obrigatório está ausente
- Um valor de parâmetro tem o tipo ou formato incorreto
- O corpo da solicitação está malformado
O que fazer: Releia a documentação do endpoint e verifique cada parâmetro obrigatório. Registre a URL completa da solicitação para detectar erros de digitação.
if (res.status === 400) {
const { error } = await res.json()
console.error("Bad request:", error)
// do not retry, fix the parameters first
}401 Não autorizado
Não cobrado. Retornado para problemas de autenticação e limitação de taxa. Verifique a mensagem de erro para distingui-los.
Seu cabeçalho x-api-key está ausente ou contém um valor não reconhecido.
Correção: Copie sua chave do seu painel de controle → Chaves de API e certifique-se de que o cabeçalho x-api-key esteja presente em cada solicitação.
A chave existe mas foi desativada.
Correção: Vá ao seu painel de controle → Chaves de API e ative a chave, ou gere uma nova.
A chave ultrapassou sua data de expiração.
Correção: Gere uma nova chave ou estenda a expiração no seu painel de controle.
Você enviou muitas solicitações em um curto período.
Correção: Aguarde antes de tentar novamente. Se isso ocorrer com frequência, considere atualizar seu plano.
if (res.status === 401) {
const { error } = await res.json()
if (error.toLowerCase().includes("rate limit")) {
await new Promise(r => setTimeout(r, 2000))
// retry
}
}402 Pagamento necessário
Não cobrado. Seu saldo de créditos está vazio. A solicitação não foi executada.
O que fazer:
- Recarregue seu saldo no seu painel de controle.
- Ou ative a Recarga automática para evitar que isso aconteça novamente.
A recarga automática só é ativada quando seu saldo cai abaixo do limite configurado. Ela nunca é executada em um horário fixo ou programado. Um período de espera de 72 horas integrado também impede múltiplas cobranças em pouco tempo: uma vez que uma recarga é feita, ela não pode ser ativada novamente por 72 horas independentemente de como seu saldo se mova. Se uma cobrança falhar, a recarga automática é desativada automaticamente para proteger sua conta.
Não tente novamente uma resposta 402 imediatamente. A chamada falhará novamente até você adicionar créditos. Configure um alerta para que sua equipe seja notificada quando isso acontecer.
if (res.status === 402) {
// alert your team or trigger an auto top-up flow
throw new Error("Insufficient credits. Top up at https://app.chartquery.com")
}403 Proibido
Não cobrado. Sua chave não tem permissão para acessar este endpoint.
O que fazer: Verifique se as permissões da sua chave cobrem o endpoint que você está chamando. Entre em contato com o suporte se acredita que é um erro.
404 Não encontrado
Pode ser cobrado (específico do endpoint). O recurso não foi encontrado. Verifique a documentação do endpoint para confirmar se esta resposta é cobrada.
if (res.status === 404) {
// handle "no result" gracefully, not as a fatal error
return null
}500 Erro interno do servidor
Não cobrado. Ocorreu um erro inesperado do nosso lado.
O que fazer: Tente novamente com backoff exponencial. Se o problema persistir, entre em contato com o suporte.
async function fetchWithRetry(url: string, options: RequestInit, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const res = await fetch(url, options)
if (res.status !== 500 || attempt === maxRetries) return res
const delay = 500 * 2 ** attempt
console.warn(`500 error, retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})`)
await new Promise(r => setTimeout(r, delay))
}
}Tratador de erros completo
Uma única função que cobre cada código de status:
interface ApiResult<T> {
data: T | null
error: string | null
status: number
billed: boolean
}
async function apiCall<T>(url: string, apiKey: string): Promise<ApiResult<T>> {
const res = await fetch(url, {
headers: { "x-api-key": apiKey },
})
// 200 and 201 are always billed; 404 billing is endpoint-specific
const billed = res.status === 200 || res.status === 201
if (res.status === 200) {
return { data: await res.json() as T, error: null, status: 200, billed }
}
const body = await res.json().catch(() => ({ error: "Unknown error" }))
const error = body?.error ?? "Unknown error"
switch (res.status) {
case 400:
console.error("[400] Bad request, fix your parameters:", error)
break
case 401:
if (error.toLowerCase().includes("rate limit")) {
console.warn("[401] Rate limit, back off and retry")
} else {
console.error("[401] Auth error, check your API key:", error)
}
break
case 402:
console.error("[402] No credits remaining. Top up at https://app.chartquery.com")
break
case 403:
console.error("[403] Forbidden, check your key permissions")
break
case 404:
console.warn("[404] Not found, no result for this request")
break
case 500:
console.error("[500] Server error, retry with backoff")
break
default:
console.error(`[${res.status}] Unexpected status:`, error)
}
return { data: null, error, status: res.status, billed }
}Estratégia de nova tentativa
| Status | Tentar novamente? | Estratégia |
|---|---|---|
400 | Não | Corrigir a solicitação primeiro |
401 (limite de taxa) | Sim | Aguardar 2–5 s, depois tentar novamente |
401 (auth) | Não | Corrigir a chave de API |
402 | Não | Adicionar créditos primeiro |
403 | Não | Verificar permissões |
404 | Não | Tratar como resultado vazio |
500 | Sim | Backoff exponencial (máx. 3 tentativas) |
Resumo de cobrança
| Status | Cobrado |
|---|---|
200 | Sim |
201 | Sim |
404 | Específico do endpoint (consulte a documentação) |
| Todos os outros códigos | Não |
Consulte a página Créditos para um detalhamento completo de custos por endpoint. Para conselhos mais amplos de integração, consulte Melhores práticas.