Skip to content

fix: harden unhandled rejections in main process + observability - #34

Open
RVerdiF wants to merge 1 commit into
caribeedu:mainfrom
RVerdiF:feat/harden-phase4-main
Open

fix: harden unhandled rejections in main process + observability#34
RVerdiF wants to merge 1 commit into
caribeedu:mainfrom
RVerdiF:feat/harden-phase4-main

Conversation

@RVerdiF

@RVerdiF RVerdiF commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

Fase 4 — hardening de unhandled promise rejections (main) + safety nets

Parte 4 do plano hardening-dogwalker-unhandled-rejections, somente processo principal e safety nets. Nenhuma mudança em src/app/ (Fases 1-3 ficam para depois).

Mudanças

  • src/main/broker.ts.catch no despacho de handleAsk (o Promise.all interno pode rejeitar, ex.: PTY morre no meio do ask) respondendo {ok:false,error} ao socket IPC; .catch no despacho de handlePortal cobrindo o resíduo fora do try interno (op=new e wiring pré-try). O try interno (494-539) não foi duplicado.
  • src/main/ptyManager.ts.catch defensivo no setInterval(checkMemory) (poller de RAM), loga [dw] memory check failed.
  • src/main/routineService.ts.catch defensivo no setInterval(tick) do scheduler, loga [dw] routine <id> tick failed.
  • src/main.tsprocess.on(unhandledRejection) loga rejeições que escapam dos catches locais.
  • src/renderer.tsxwindow.addEventListener(unhandledrejection) loga rejeições do renderer (espelhado no stdout do main).

Safety nets são APENAS observabilidade — nunca recuperação, nunca substituto de catch local (Opção B do plano, padrão PR #33).

Testes (colocalizados, cada catch novo com teste de rejeição)

  • src/main/broker.test.ts — ask explodindo no meio do exchange → {ok:false, error}; portal op=new lançando fora do try interno → {ok:false, error}.
  • src/main/ptyManager.test.ts — poller de memória rejeitando (listProcesses mockRejectedValue) → loga, sem unhandled rejection.
  • src/main/routineService.test.tstick lançando pré-try (onUpdate) no ciclo do intervalo → loga, sem unhandled rejection.

Verificação

  • npm run typecheck ✓ · npm run lint ✓ (0 erros; 3 warnings pré-existentes) · vitest run ✓ 392/392 · vitest run --coverage ✓ (44.99/42.67/39.66/46.04 acima do ratchet 41/39/36/42)

Base: main (274d6c3) — não empilhado sobre PRs #31/#32/#33.

Fase 4 of the unhandled-rejection hardening plan:
- broker: catch handleAsk dispatch (Promise.all can reject mid-ask) and
  handlePortal residue (op=new / pre-try wiring) — answer the socket with
  the error instead of leaking an unhandled rejection. The internal try
  for portal ops is untouched.
- ptyManager: defensive catch on the memory-poll interval (checkMemory).
- routineService: defensive catch on the routine scheduler interval (tick).
- main.ts + renderer.tsx: global unhandledRejection listeners as
  observability-only safety nets (structured logs, never recovery).

Tests: rejection-path coverage for every new catch (broker ask explosion,
portal op=new explosion, memory poll failure, tick pre-try throw).
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.

1 participant