Skip to content

fix: notifica falhas silenciosas de QR no Chatwoot e reconcilia estado zumbi#2657

Open
PhyBruno wants to merge 6 commits into
evolution-foundation:developfrom
PhyBruno:fix/problemas-3-4-chatwoot-e-estado-zumbi
Open

fix: notifica falhas silenciosas de QR no Chatwoot e reconcilia estado zumbi#2657
PhyBruno wants to merge 6 commits into
evolution-foundation:developfrom
PhyBruno:fix/problemas-3-4-chatwoot-e-estado-zumbi

Conversation

@PhyBruno

Copy link
Copy Markdown

Problemas

  1. QR solicitado pelo Chatwoot as vezes nao aparece na conversa - ocorre mesmo com a instancia genuinamente desconectada, nao so em cenario de estado "zumbi".
  2. Instancia aparece "conectada" na Evolution mesmo com o WhatsApp real caido (mais raro).

Causa raiz

Falhas silenciosas (Chatwoot):

  • receiveWebhook (comando init) e o handler de qrcode.updated, em chatwoot.service.ts, tem try/catch que so loga no servidor, sem nenhum feedback visivel ao operador do Chatwoot.
  • Bug de optional chaining: body?.qrcode.base64 protege body mas nao body.qrcode - se qrcode vier undefined, lanca TypeError capturado silenciosamente pelo catch.

Estado zumbi:

  • O status de conexao e 100% orientado a evento (connection.update). Se esse evento nunca dispara (ex. socket morrendo sem RST/FIN, cenario plausivel sob carga de rede/CPU instavel), o valor cacheado em memoria/banco fica preso em 'open' indefinidamente.
  • Confirmado: zero ocorrencias de setInterval em todo src/ antes deste PR - nenhuma sonda ativa existia para reconciliar esse estado.

Mudancas

  • receiveWebhook: erro ao conectar agora notifica a conversa (cw.inbox.qrError); catch geral tambem notifica erro generico (cw.inbox.requestError) alem de logar.
  • Corrigido o optional chaining (body?.qrcode?.base64) com guarda explicita e notificacao de erro.
  • Handler de qrcode.updated: catch notifica cw.inbox.qrError, mas so quando o QR ainda nao tinha sido postado com sucesso (flag qrPosted) - evita notificar erro logo depois que a imagem do QR ja chegou na conversa (ex. se so a mensagem de texto que acompanha o QR falhar).
  • monitor.service.ts: health check periodico (30s) que confirma via client.ws.isOpen (propriedade real do AbstractSocketClient do Baileys) se instancias marcadas 'open' realmente tem socket ativo; se nao, reconcilia o estado para 'close' (banco + webhook CONNECTION_UPDATE), reaproveitando os mesmos campos ja usados no fechamento real da conexao.
  • instance.controller.ts: connectionState reconcilia sob demanda antes de responder, alem do health check periodico.
  • Novas chaves de traducao cw.inbox.qrError/cw.inbox.requestError em pt-BR/en/es.

Deliberadamente nao foi adicionado um listener extra de close/error no WebSocket do Baileys: o proprio Baileys ja trata isso internamente e emite connection.update; um segundo listener nosso criaria risco de reconexao/processamento duplicado.

Validacao

  • npx tsc --noEmit: sem erros.
  • npx eslint --ext .ts src: sem erros/warnings.
  • Sem alteracao de dependencias.

DavidsonGomes and others added 6 commits May 6, 2026 13:58
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…n-foundation

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…o zumbi

Dois problemas distintos, mas relacionados:

1) QR solicitado pelo Chatwoot as vezes simplesmente nao aparecia na
   conversa - mesmo com a instancia genuinamente desconectada, nao so
   em cenario de estado "zumbi". Causa: falhas engolidas em silencio.
   receiveWebhook (comando 'init') e o handler de qrcode.updated
   estavam em try/catch que so logava no servidor, sem nenhum feedback
   ao operador no Chatwoot. Havia tambem um bug de optional chaining
   (body?.qrcode.base64) que podia lancar TypeError silencioso se
   body.qrcode viesse undefined.

2) Instancia aparecia "conectada" na Evolution mesmo com o WhatsApp
   real caido. Causa: o status de conexao e 100% orientado a evento
   (connection.update); se esse evento nunca dispara (ex. socket
   morrendo sem RST/FIN, comum sob CPU steal alto), o valor cacheado
   em memoria/banco fica preso em 'open' para sempre. Nao havia
   nenhuma sonda ativa (confirmado: zero ocorrencias de setInterval em
   todo o src/).

Mudancas:
- receiveWebhook: erro ao conectar agora notifica a conversa
  (cw.inbox.qrError); catch geral tambem notifica erro generico
  (cw.inbox.requestError) alem de logar.
- Corrigido o optional chaining (body?.qrcode?.base64) com guarda
  explicita e notificacao de erro.
- Handler de qrcode.updated: catch notifica cw.inbox.qrError, mas so
  quando o QR ainda nao tinha sido postado com sucesso (flag
  qrPosted) - evita notificar erro depois que a imagem do QR ja
  chegou na conversa.
- monitor.service.ts: health check periodico (30s) que confirma via
  client.ws.isOpen se instancias marcadas 'open' realmente tem socket
  ativo; se nao, reconcilia o estado para 'close' (banco + webhook
  CONNECTION_UPDATE), reaproveitando os mesmos campos ja usados no
  fechamento real da conexao.
- instance.controller.ts: connectionState reconcilia sob demanda antes
  de responder, alem do health check periodico.
- Novas chaves de traducao cw.inbox.qrError/cw.inbox.requestError em
  pt-BR/en/es.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @PhyBruno, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@PhyBruno
PhyBruno changed the base branch from main to develop July 24, 2026 20:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants