Skip to content

feat: crash diagnostics - #70

Open
Horuse wants to merge 3 commits into
mainfrom
feat/crash-diagnostics
Open

Horuse wants to merge 3 commits into
mainfrom
feat/crash-diagnostics

Conversation

@Horuse

@Horuse Horuse commented Oct 25, 2026

Copy link
Copy Markdown
Owner

What does this PR do?

Makes crash reports useful when there is no stack

  • Session log on disk. The log is mirrored to session.log in the app log dir and capped at 4 MB. On start the old file becomes previous-session.log; after an unclean exit its last 300 lines go into the crash report.
  • Main-thread hang detection. A watchdog thread probes the main thread with run_on_main_thread. After 5 s without an answer it writes hang.json, naming the IPC command the main thread is stuck in. If the app is then killed, the next launch shows a hang ("Not responding") report instead of "did not shut down cleanly".
  • Webview errors. onerror and unhandledrejection are written to the same log through log_frontend.
  • Redaction. Before the log is attached, the home directory becomes ~ and IP addresses become <ip>, since reports end up in public issues.
  • Error modal. Shows a "Session log" block. "Copy details" includes the full log; the GitHub link includes the last 60 lines (URL length).
  • Debug panel. Adds "Main thread hang (20 s)".

Why is this the right approach?

  • Logging: tracing-appender's non-blocking writer in non-lossy mode. Its rolling appender rotates only by time, and we need one file per session, so rotation stays ours.
  • Hangs: no crate or Sentry Rust SDK feature detects hangs, so the watchdog is ours. The marker is written synchronously, so it survives a kill.
  • Redaction: regex was already in the tree through tracing-subscriber. Candidates are confirmed with std's Ipv4Addr/Ipv6Addr parsers.
  • Out of scope: minidumps (crash-handler + minidumper, including dumps on hang) and Sentry come later, in separate PRs.

Checklist

  • Diff is limited to the change, no unrelated edits
  • bun run check passes
  • cargo check --manifest-path src-tauri/Cargo.toml passes
  • bun run format leaves the tree clean
  • Generated TS types are committed with the Rust change (none)
  • New dependencies explained above (tracing-appender, regex)
  • No changes to the RT audio path; nothing logs from audio callbacks

Platform coverage

  • Developed on: macOS
  • Tested on: macOS (dev build)
  • What I did to test: "Main thread hang" from the debug panel, then a kill, then a relaunch. The modal showed a hang report naming debug_hang, with the previous session log. Recovery after a hang is logged. Unit tests cover redaction.
  • Not tested: Windows, Linux

No per-OS files. The watchdog relies on run_on_main_thread, and the log dir comes from Tauri's app_log_dir on every platform.

The log is mirrored to session.log through tracing-appender's non-blocking writer; after an unclean exit the tail of the previous session is attached to the crash report. A watchdog probes the main thread and, when it stays blocked, leaves a marker naming the command it is stuck in, so a killed 'Not responding' window is reported as a hang instead of a bare unexpected exit. Webview errors are logged to the same file.
…logs

The session log attached to a crash report can end up in a public issue, so the home directory is replaced with ~ and IP addresses with <ip>.
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