Skip to content

fix: EditEntryDialog para de ler err.message, mascarado em produção (closes #122) - #137

Draft
Guiroos wants to merge 2 commits into
mainfrom
claude/quirky-johnson-72cv6d
Draft

fix: EditEntryDialog para de ler err.message, mascarado em produção (closes #122)#137
Guiroos wants to merge 2 commits into
mainfrom
claude/quirky-johnson-72cv6d

Conversation

@Guiroos

@Guiroos Guiroos commented Sep 1, 2026

Copy link
Copy Markdown
Owner

O que mudou

components/devedores/EditEntryDialog.tsx era o último site do repo lendo err.message para decidir a mensagem de erro exibida ao usuário. Erro que atravessa a fronteira de Server Action chega ao cliente RSC reconstruído como um Error genérico em build de produção (resolveErrorProd), então err instanceof Error é sempre verdadeiro e .message é sempre o mesmo parágrafo em inglês sobre "Server Components render" — a string pt-BR 'Erro ao editar lançamento.' já existia no arquivo e nunca era exibida.

} catch (err) {
-  toast.error(err instanceof Error ? err.message : 'Erro ao editar lançamento.')
+  console.error('[EditEntryDialog] updateDebtEntry falhou', err)
+  toast.error('Erro ao editar lançamento.')
}

Por que dessa forma

Segui a proposta da issue à risca:

Como testei

  • npm run lint && npm run format:check && npm run typecheck && npm test && npm run build — todos verdes (35 arquivos, 528 testes).
  • Novo arquivo __tests__/unit/no-err-message.test.ts — gate por string sobre o código-fonte (precedente: row-actions.test.ts), varre app/**/*.tsx e components/**/*.tsx procurando err.message/error.message dentro de um catch. Validado manualmente que o regex: (a) rejeita o código anterior ao fix, (b) passa com a correção, (c) não gera falso-positivo em FeedbackDialog.tsx, que usa errors.message como chave de mapa de validação de formulário, sem relação com exceção.
  • npm run test:integration não foi rodado — exige credenciais do Neon e só roda em push para main; esta mudança não toca camada de banco.

Risco e o que NÃO foi coberto

  • Não há teste de render (o projeto não tem @testing-library/react); a cobertura fica no nível de gate por texto-fonte, mesmo padrão de achados de a11y/tipos anteriores.
  • Nada fora do bloco catch de EditEntryDialog.tsx foi tocado.

Arquivos tocados

  • components/devedores/EditEntryDialog.tsx
  • __tests__/unit/no-err-message.test.ts (novo)

Closes #122


Generated by Claude Code

O único err.message que sobrava no repo (o resto foi convertido na #34)
sempre exibe o parágrafo genérico do React em produção, porque erro que
atravessa a fronteira de Server Action chega ao cliente reconstruído
como Error genérico. A string pt-BR já existia no arquivo e nunca era
exibida.

Closes #122

@Guiroos Guiroos left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Revisão do head 6536541. A correção em si está certa e fecha a #122 por inteiro — reconferi a enumeração pelo conteúdo, não pelo caminho: grep -rnE '\b(err|error|e)\s*\.\s*message\b' sobre app/, components/ e lib/ devolve zero ocorrências depois do PR, então não sobrou site fora do recorte da issue (que só falava de .tsx). O par console.error + string pt-BR fixa é o padrão já estabelecido pela correção da #35 em ui/row-actions.tsx, e a decisão de não converter updateDebtEntry para ActionResult está declarada no corpo e alinhada ao julgamento registrado na #34 — nada de substituição silenciosa de proposta.

O gate novo cobre de verdade, e verifiquei em vez de assumir: revertendo EditEntryDialog.tsx para a linha anterior e rodando npx vitest run __tests__/unit/no-err-message.test.ts, ele fica vermelho; com a correção, verde (suíte cheia: 34 arquivos, 527 testes, mais lint e typecheck limpos nesta sessão). Também derruba as duas correções erradas que a issue nomeou, porque as duas continuam lendo .message.

Um achado, não-bloqueante, e é sobre o regex, não sobre o fix: a janela catch[\s\S]{0,200}? foi copiada literal da issue junto com a justificativa dela — "sem ela o gate nasce falso-positivo" —, e essa justificativa é falsa. Medi: o regex sem a janela dá zero hits nos 171 .tsx de app/ + components/, FeedbackDialog.tsx incluído. Em troca, a janela abre um ponto cego de 241 chars no formato console.error(...) + toast.error(...) — o padrão que este próprio PR institui. Correção de uma linha, com a alternativa já verificada contra os mesmos arquivos, no comentário inline.


Generated by Claude Code

Comment thread __tests__/unit/no-err-message.test.ts Outdated
…e catch

A janela catch[\s\S]{0,200}? ficava cega assim que um console.error(...)
— o próprio remédio que este arquivo institui — empurrava o toast.error(...)
para fora dela. O falso-positivo que a janela existia para evitar
(errors.message, next.message como chave de mapa de formulário) não
ocorre de fato: \b antes de err/error/e não casa no meio de "errors"/"next".

Ancorar no sink (toast.*) em vez de numa distância é mais fiel ao achado
da #122: o defeito não é ler err.message, é exibi-lo ao usuário.

Aponta review em #137

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Wgc6FNhxJPveiPvq6PjQd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants