Pular para o conteúdo principal

Códigos de Erro

O WebSocket pode fechar a conexão com códigos de erro específicos. Além dos códigos padrão do WebSocket, o VoxFi usa códigos customizados na faixa 4000-4999.

Códigos Customizados VoxFi

4001 - Unauthorized

Causa: Chave de API inválida ou ausente ao tentar se inscrever no canal user. Quando ocorre: Ao tentar se inscrever no canal user sem fornecer auth ou com uma chave de API inválida. Solução:
  • Verifique se você está fornecendo o campo auth na mensagem de subscribe;
  • Confirme que a chave de API está correta e ativa;
  • Verifique se a chave de API não expirou ou foi desabilitada;
  • Verifique se seu IP está na whitelist da chave de API.

4002 - Invalid Params

Causa: Parâmetros inválidos na conexão. Quando ocorre: Durante a validação inicial da conexão, quando dados de sessão são inválidos ou ausentes. Mensagens de erro comuns:
  • "session is required": Sessão inválida ou ausente
Solução: Verifique se está usando a URL correta do WebSocket e se a conexão está sendo estabelecida corretamente.

4003 - Server Error

Causa: Erro interno do servidor. Quando ocorre: Quando ocorre um erro inesperado no servidor ao processar sua requisição. Solução: Tente novamente após alguns segundos. Se o problema persistir, entre em contato com o suporte.

4004 - Invalid Message

Causa: Mensagem inválida ou parâmetros incorretos na mensagem de subscribe/unsubscribe. Quando ocorre: Ao enviar mensagens com formato ou conteúdo inválido. Possíveis causas:
  • Campo channel inválido (deve ser "user", "market" ou "event");
  • Campo filter inválido (deve ser "all", "orderbook", "trades" ou vazio);
  • Campos obrigatórios ausentes (markets para canal market, events para canal event, auth para canal user);
  • Formato JSON inválido;
  • Tipo de mensagem inválido (deve ser "subscribe" ou "unsubscribe").
Mensagens de erro comuns:
  • "invalid channel": Canal especificado não existe;
  • "invalid filter": Filtro especificado é inválido;
  • "invalid message type": Tipo de mensagem inválido.
Solução: Verifique a estrutura da mensagem e certifique-se de que todos os campos obrigatórios estão presentes e no formato correto.

Códigos Padrão WebSocket

Além dos códigos customizados, o WebSocket pode retornar códigos padrão:
  • 1000: Fechamento normal (não é um erro);
  • 1001: Endpoint indo embora;
  • 1002: Protocol error (erro de protocolo);
  • 1006: Conexão fechada anormalmente (sem código de fechamento);
  • 1011: Erro interno do servidor.

Tratamento de Erros

const ws = new WebSocket('wss://data-ws.voxfi.com.br');

ws.onerror = (error) => {
  console.error('Erro no WebSocket:', error);
};

ws.onclose = (event) => {
  console.log('Conexão fechada:', event.code, event.reason);
  
  // Tratar diferentes códigos de erro
  switch (event.code) {
    case 4001:
      console.error('Não autorizado. Verifique sua chave de API.');
      break;
    case 4002:
      console.error('Parâmetros inválidos. Verifique a conexão.');
      break;
    case 4003:
      console.error('Erro do servidor. Tente novamente mais tarde.');
      break;
    case 4004:
      console.error('Mensagem inválida. Verifique o formato da mensagem.');
      break;
    case 1002:
      console.error('Erro de protocolo. Verifique a URL e formato das mensagens.');
      break;
    case 1006:
      console.error('Conexão fechada anormalmente. Possível problema de rede.');
      break;
    default:
      console.error('Erro desconhecido:', event.code, event.reason);
  }
  
  // Implementar reconexão se necessário
  if (event.code !== 1000) { // 1000 = fechamento normal
    setTimeout(() => {
      console.log('Tentando reconectar...');
      connect(); // Sua função de conexão
    }, 5000);
  }
};

Mensagens de Erro

Além dos códigos de fechamento, o WebSocket retorna mensagens de erro no campo reason ao fechar a conexão. Essas mensagens fornecem detalhes específicos sobre o erro:

Mensagens de Erro Comuns

  • "session is required" (código 4002): Sessão inválida ou ausente durante a validação inicial;
  • "invalid channel" (código 4004): Canal especificado não existe (deve ser "user", "market" ou "event");
  • "invalid filter" (código 4004): Filtro especificado é inválido (deve ser "all", "orderbook", "trades" ou vazio);
  • "invalid message type" (código 4004): Tipo de mensagem inválido (deve ser "subscribe" ou "unsubscribe");
  • "failed to check x-api-key" (código 4001): Falha ao validar a chave de API;
  • Mensagens de erro JSON do Go quando há falha ao fazer unmarshal da mensagem (código 4004).

Boas Práticas de Tratamento de Erros

  1. Sempre Trate onclose: Implemente tratamento para o evento onclose para detectar desconexões;
  2. Verifique Códigos de Erro: Use os códigos de erro para determinar a causa e tomar ações apropriadas;
  3. Reconexão Inteligente: Implemente reconexão automática com backoff exponencial para erros temporários;
  4. Não Reconecte para Erros Permanentes: Erros como 1003 (não autorizado) ou 1008 (mensagem inválida) indicam problemas que precisam ser corrigidos antes de reconectar;
  5. Logging: Registre todos os erros para debugging e monitoramento;
  6. Validação Prévia: Valide mensagens antes de enviar para evitar erros 1008;
  7. Tratamento de Timeout: Implemente timeout para conexões que não respondem.

Exemplo de Reconexão com Backoff Exponencial

let reconnectDelay = 1000; // Começa com 1 segundo
const maxDelay = 60000; // Máximo de 60 segundos

function connect() {
  const ws = new WebSocket('wss://data-ws.voxfi.com.br');
  
  ws.onopen = () => {
    console.log('Conectado');
    reconnectDelay = 1000; // Reset delay em caso de sucesso
    // Reinscrever-se em todos os canais
    resubscribe(ws);
  };
  
  ws.onclose = (event) => {
    console.log('Conexão fechada:', event.code);
    
    // Não reconectar para erros permanentes
    if (event.code === 4001 || event.code === 4002 || event.code === 4004) {
      console.error('Erro permanente. Corrija o problema antes de reconectar.');
      return;
    }
    
    // Reconectar com backoff exponencial
    setTimeout(() => {
      console.log(`Tentando reconectar em ${reconnectDelay}ms...`);
      connect();
      reconnectDelay = Math.min(reconnectDelay * 2, maxDelay);
    }, reconnectDelay);
  };
  
  return ws;
}

function resubscribe(ws) {
  // Reinscrever-se em todos os canais que você estava inscrito
  // Mantenha uma lista de inscrições ativas
  const subscriptions = [
    { type: 'subscribe', channel: 'market', markets: ['market-id-1'] }
  ];
  
  subscriptions.forEach(sub => {
    ws.send(JSON.stringify(sub));
  });
}