TRILHA 6

🚑 Troubleshooting & Dicas Avançadas

Quando algo quebra — e vai quebrar. Mapa de erros comuns do OpenHuman, filosofia de debug logging e dicas avançadas para não cair nas mesmas armadilhas que todo mundo cai.

3
Módulos
21
Tópicos
~2h
Duração
Salva-vidas
Nível

Mapa da trilha

Conteúdo detalhado

6.1 ~40 min

🐛 Erros comuns

CEF lib panic, sidecar legado, token bearer, deep links macOS e pre-push. O bestiário do OpenHuman.

O que é:

Panic no boot do app: o runtime CEF tenta carregar Chromium e não acha — porque o bundle está incompleto.

Por que aprender:

É o erro nº1 de quem usa o @tauri-apps/cli stock. O fix é simples mas pouco óbvio: usar o CLI vendored.

Conceitos-chave:

CLI vendored em app/src-tauri/vendor/tauri-cef; pnpm tauri:ensure; reinstalar com cargo install --locked --path.

O que é:

Em PR #1061 o sidecar foi removido. O core agora roda in-process como tokio task dentro do Tauri.

Por que aprender:

Docs antigos mandam rodar pnpm core:stage — hoje é apenas um echo. Procurar por sidecar quebra a cabeça à toa.

Conceitos-chave:

CoreProcessHandle, lifecycle atrelado ao Cmd+Q, RPC HTTP local em 127.0.0.1:<port>/rpc.

O que é:

O core autentica chamadas com um bearer hex gerado a cada launch. Sem ele no header, tudo retorna 401.

Por que aprender:

Quando o core é externo (debug), o token vive em {workspace}/core.token. Não copiar = sign-in pendurado.

Conceitos-chave:

OPENHUMAN_CORE_REUSE_EXISTING=1; per-launch token; bearer em Authorization: Bearer ....

O que é:

A propriedade window.__TAURI__ não existe no module load — checar direto resulta em false espúrio.

Por que aprender:

Bypass do wrapper contractual quebra detecção de ambiente. Sempre use isTauri() de webviewAccountService.

Conceitos-chave:

Wrapper canônico; try/catch ao redor de invoke(); nunca acessar globals Tauri direto.

O que é:

Chamar o core RPC via fetch() dispara OPTIONS preflight do navegador — e falha por falta de CORS.

Por que aprender:

O caminho correto é invoke('core_rpc_relay', ...) que vai por IPC nativo, sem CORS.

Conceitos-chave:

Tauri IPC vs fetch; coreRpcClient abstrai isso; nunca chamar HTTP local direto da UI.

O que é:

Deep links openhuman://... em macOS geralmente só funcionam quando o app está rodando como .app assinado, não em tauri dev.

Por que aprender:

Testar OAuth callback no dev e jurar que "está quebrado" é perda de hora. Faça build do bundle antes.

Conceitos-chave:

Launch Services; URL scheme registrado pelo Info.plist do bundle; pnpm test:e2e:build.

O que é:

O Husky pre-push roda pnpm rust:check. Às vezes o main tem breakage não relacionado ao seu PR.

Por que aprender:

A regra: se a falha é em código que você NÃO tocou, --no-verify é OK — declare no PR. Se é seu, fix antes.

Conceitos-chave:

Husky; CI vai re-rodar de qualquer jeito; só nunca skip hooks em commits/sign que você assinou.

Ver Completo
6.2 ~40 min

📜 Debug logging

Verbose por padrão, prefixos grep-friendly, correlation IDs, scripts/debug com tee, mock API admin.

O que é:

CLAUDE.md exige: novos fluxos sempre com logs ricos — entry/exit, branches, external calls, retries, estados.

Por que aprender:

Mudança sem log de diagnose é considerada incompleta. PR vai voltar.

Conceitos-chave:

Logs como contrato de manutenção; "diagnose now, optimize later"; nunca logar secrets/PII.

O que é:

Padronizar prefixos no início da mensagem permite filtrar com grep "\[memory\]" em segundos.

Por que aprender:

Sem prefixo, log fica indistinguível. Com prefixo + correlation ID, você reconstrói qualquer fluxo.

Conceitos-chave:

Prefixos por domínio; correlation IDs (request_id, entity_id); método sempre presente.

O que é:

No core, use tracing::debug! ou log::debug! com campos estruturados. trace! para muito ruído.

Por que aprender:

Tracing permite spans correlacionados — uma request inteira tem o mesmo ID em todos os módulos.

Conceitos-chave:

#[instrument]; RUST_LOG=openhuman=debug; spans aninhados; campos estruturados.

O que é:

No app, use a lib debug com namespaces (openhuman:chat, openhuman:rpc) — ativável seletivamente.

Por que aprender:

Console limpo em prod, verbose seletivo em dev (localStorage.debug = 'openhuman:*').

Conceitos-chave:

Wildcards; só dev-only detail; nunca console.log nu em produção.

O que é:

pnpm debug {unit|e2e|rust} roda os tests com output truncado e tee para target/debug-logs/.

Por que aprender:

Salva contexto de agente E preserva log completo no disco para inspeção depois.

Conceitos-chave:

pnpm debug logs last; --tail N; --verbose para stream raw.

O que é:

O mock backend expõe endpoints admin para inspecionar requisições recebidas, resetar estado e injetar behaviors.

Por que aprender:

Em vez de print/log, consulte GET /__admin/requests e veja exatamente o que o app mandou.

Conceitos-chave:

POST /__admin/reset; POST /__admin/behavior; pnpm mock:api.

O que é:

O event bus do core já vem com TracingSubscriber que loga todo DomainEvent publicado.

Por que aprender:

Para entender ordem de eventos cross-domain, basta ligar o subscriber e ler — não precisa instrumentar manual.

Conceitos-chave:

subscribe_global; filtro por domains(); debug de subscribers próprios via name().

Ver Completo
6.3 ~40 min

💎 Dicas avançadas

i18n strict, sem dynamic import, file size, controllers, light mod.rs, event bus owned, webview zero-injection.

O que é:

Toda string UI passa por useT(). Adicionar uma chave exige atualizar en.ts + chunk en-N.ts + mesma chunk em TODOS os locales.

Por que aprender:

CI enforça via pnpm i18n:check. Faltar chave em qualquer locale falha o gate.

Conceitos-chave:

12 locales (ar, bn, de, es, fr, hi, id, it, ko, pt, ru, zh-CN); English como placeholder; chunks 1-5.

O que é:

No app, import(), React.lazy(() => import(...)) e await import(...) são banidos em produção.

Por que aprender:

Static import + try/catch ou runtime guard. Exceções: tests, .d.ts, config files.

Conceitos-chave:

Bundle previsível; sem chunk loading runtime; import type sempre OK.

O que é:

Preferência: arquivos com até ~500 linhas. Acima disso, dividir em sub-módulos.

Por que aprender:

Módulos grandes acumulam responsabilidade e ficam ilegíveis. Filosofia Unix.

Conceitos-chave:

Sharp-responsibility; ops.rs/store.rs/types.rs; export-focused mod.rs.

O que é:

Para expor RPC/CLI, registre o domínio na controller registry. NUNCA adicione branches em dispatch.rs.

Por que aprender:

Branches manuais em core/ reintroduzem o acoplamento que controllers vieram remover.

Conceitos-chave:

all_controller_schemas; all_registered_controllers; wire em src/core/all.rs.

O que é:

mod.rs só declara módulos e re-exports. Lógica vai em ops.rs, store.rs, types.rs.

Por que aprender:

Mantém o "índice" do domínio claro. mod.rs gordo esconde responsabilidades.

Conceitos-chave:

Subdir por domínio; novo código em arquivos siblings; dev_paths.rs/util.rs são exceções grandfathered.

O que é:

Tipos passados no event bus precisam ser owned (Arc, channels, fields), Send + 'static — não Serialize, não borrows.

Por que aprender:

É request/response tipado in-process, não JSON-RPC. Lifetime de borrows não vive no canal.

Conceitos-chave:

register_native_global; oneshot::Sender para reply; método "domain.verb".

O que é:

Webviews de provider (whatsapp, slack, telegram, discord) NÃO recebem JS injetado. Tudo via CDP nativo.

Por que aprender:

JS injetado em origem de terceiro = surface de ataque + scraping frágil. Migração explicitamente proibe novos scripts.

Conceitos-chave:

Network.*/Emulation.*/Input.* CDP; LoadHandler; cuidado com plugins (ex.: tauri-plugin-opener).

Ver Completo
← Trilha anterior
🛠️ Desenvolvimento & Contribuição
Voltar ao início →
🏠 Página principal do curso