> ## Documentation Index
> Fetch the complete documentation index at: https://docs.voxfi.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Erros

> Tratamento de erros e códigos de erro do WebSocket

## 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

<CodeGroup>
  ```javascript JavaScript theme={null}
  const ws = new WebSocket('wss://data-ws-dev.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);
    }
  };
  ```

  ```python Python theme={null}
  import asyncio
  import websockets
  import json

  async def connect_with_error_handling():
      uri = "wss://data-ws-dev.voxfi.com.br"
      
      try:
          async with websockets.connect(uri) as websocket:
              # Sua lógica aqui
              await websocket.send(json.dumps({
                  "type": "subscribe",
                  "channel": "market",
                  "markets": ["market-id-1"]
              }))
              
              async for message in websocket:
                  data = json.loads(message)
                  print("Mensagem recebida:", data)
                  
      except websockets.exceptions.InvalidStatusCode as e:
          print(f"Erro de conexão: {e.status_code}")
          if e.status_code == 403:
              print("Não autorizado. Verifique sua chave de API.")
      except websockets.exceptions.ConnectionClosed as e:
          print(f"Conexão fechada: código {e.code}, razão: {e.reason}")
          
          if e.code == 4001:
              print("Não autorizado. Verifique sua chave de API.")
          elif e.code == 4002:
              print("Parâmetros inválidos. Verifique a conexão.")
          elif e.code == 4003:
              print("Erro do servidor. Tente novamente mais tarde.")
          elif e.code == 4004:
              print("Mensagem inválida. Verifique o formato da mensagem.")
          elif e.code == 1002:
              print("Erro de protocolo. Verifique a URL e formato das mensagens.")
          elif e.code == 1006:
              print("Conexão fechada anormalmente. Possível problema de rede.")
      except Exception as e:
          print(f"Erro inesperado: {e}")

  asyncio.run(connect_with_error_handling())
  ```
</CodeGroup>

## 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

```javascript theme={null}
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-dev.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));
  });
}
```
