Skip to main content

Visão Geral

A API de Importação NovaGestão retorna erros estruturados que facilitam o tratamento programático de problemas.

Estrutura de Erro

Todos os erros GraphQL seguem este formato:
{
  "errors": [
    {
      "message": "Organization not found",
      "code": "ORGANIZATION_NOT_FOUND",
      "path": ["importCreate"],
      "locations": [{"line": 2, "column": 3}]
    }
  ]
}

Códigos de Erro Comuns

Erros de Autenticação

Causa: Chave de API ausente ou inválidaSolução:
  • Verifique se o cabeçalho Authorization está definido
  • Confirme que a chave de API tem 64 caracteres
  • Gere uma nova chave se necessário
Causa: Chave de API com escopo read_onlySolução:
  • Gere uma nova chave com escopo read_write
  • Atualize sua aplicação para usar a nova chave

Erros de Validação

Causa: Dados de entrada inválidosExemplo:
{
  "code": "VALIDATION_ERROR",
  "message": "Amount can't be blank",
  "field": "amount"
}
Solução:
  • Verifique o campo mencionado em cada registro
  • Use dry run para identificar todos os problemas
  • Corrija os dados e tente novamente
Causa: Campo obrigatório ausenteSolução:
  • Consulte a documentação da entidade para campos obrigatórios
  • Adicione os campos faltantes aos seus dados

Erros de Associação

Causa: Associação referenciada não existeExemplo:
{
  "code": "ASSOCIATION_NOT_FOUND",
  "message": "Account not found",
  "field": "accountId"
}
Solução:
  • Verifique se a conta/categoria/centro de custo existe
  • Use o ID correto ou nome para busca
  • Crie a associação primeiro se necessário

Erros de Limite de Taxa

Causa: Excedeu 1000 requisições por horaSolução:
if (response.status === 429) {
  const reset = parseInt(response.headers.get('X-RateLimit-Reset'));
  const waitMs = (reset * 1000) - Date.now();
  await sleep(waitMs);
  // Tentar novamente
}

Tratamento de Erros em Dry Run

Durante dry run, cada registro com erro inclui feedback detalhado:
{
  "previewData": [
    {
      "amount": "",
      "description": "Test",
      "_feedback": {
        "status": "invalid",
        "errors": [
          "Amount can't be blank",
          "Description is too short (minimum 5 characters)"
        ]
      }
    }
  ]
}

Exemplo de Tratamento

async function validarDados(dados) {
  const response = await fetch(endpoint, {
    method: 'POST',
    headers,
    body: JSON.stringify({
      query: dryRunMutation,
      variables: { data: dados, entityType: 'TRANSACTION' }
    })
  });

  const result = await response.json();
  const importResult = result.data.importCreate;

  if (importResult.invalidRecords > 0) {
    console.error(`❌ ${importResult.invalidRecords} registros inválidos:`);

    importResult.previewData.forEach((row, index) => {
      if (row._feedback?.status === 'invalid') {
        console.error(`\nLinha ${index + 1}:`);
        row._feedback.errors.forEach(error => {
          console.error(`  - ${error}`);
        });
      }
    });

    return false;
  }

  console.log(`✓ Todos os ${importResult.validRecords} registros são válidos`);
  return true;
}

Falhas Parciais

Importações podem ter sucesso parcial. Sempre verifique recordsFailed:
const importResult = await getImportStatus(importId);

if (importResult.status === 'completed') {
  if (importResult.recordsFailed > 0) {
    console.warn(
      `⚠️ Importação concluída com ${importResult.recordsFailed} falhas de ${importResult.recordsTotal} registros`
    );

    // Buscar registros com falha
    const failedRecords = await getFailedRecords(importId);
    failedRecords.forEach(record => {
      console.error(`Registro ${record.rowNumber}: ${record.errorMessage}`);
    });
  } else {
    console.log('✓ Todos os registros importados com sucesso!');
  }
}

Melhores Práticas

Detecte e corrija erros antes de criar importações reais.
Para erros transitórios (limite de taxa, timeouts), implemente retry exponencial.
Registre códigos de erro, mensagens e contexto para depuração.
Configure alertas para taxas de falha altas em produção.

Próximos Passos