Skip to content

Add file-based crash/diagnostics logging with in-app export - #7

Merged
HarryCordewener merged 1 commit into
masterfrom
feat/crash-logging
Jun 30, 2026
Merged

Add file-based crash/diagnostics logging with in-app export#7
HarryCordewener merged 1 commit into
masterfrom
feat/crash-logging

Conversation

@HarryCordewener

Copy link
Copy Markdown
Member

Why

After the app runs a while in the background it shows "An unhandled error has occurred" and reloads to a black screen. Rather than keep guessing at the cause, this adds persistent on-device logging that captures the real exception so it can be exported from the phone and handed back for diagnosis.

What

  • FileLogStore — thread-safe, append-only log under AppDataDirectory/logs/sharpclient.log with 512 KB size-based rotation (current + one .1 backup). Writes never throw.
  • FileLoggerProvider — routes ILogger output into the store at Information+. This captures Blazor's own Error-level log emitted for an unhandled component exception (the "unhandled error" case) before the error UI shows.
  • Global unhandled-exception hooks, all writing to the same store:
    • AndroidEnvironment.UnhandledExceptionRaiser (the reliable .NET-Android catch-all for background/network-thread crashes) — wired in MainActivity, resolves the store via DI at crash time.
    • AppDomain.CurrentDomain.UnhandledException
    • TaskScheduler.UnobservedTaskException
  • ILogExporter (Core abstraction): MauiLogExporter shares the file via the OS share sheet; NoopLogExporter (Web) reports IsAvailable == false.
  • Settings → Diagnostics → "Export log" button (Android only; hidden on Web).

How to use

On the phone: reproduce the crash, then open Settings → Diagnostics → Export log and share the file (e.g. to chat/email). The log includes the timestamped stack trace.

Testing

  • Web host: builds clean (0 warnings).
  • Android (Debug): builds clean (0 warnings).
  • UI bUnit suite: 46/46 (tests register a NoopLogExporter so SettingsView renders resolve).

🤖 Generated with Claude Code

Capture unhandled exceptions to a rotating log file on device so the user
can export it and hand it back for diagnosis (added to chase the runtime
"An unhandled error has occurred" → black-reload crash after backgrounding).

- FileLogStore: thread-safe, append-only sink under AppDataDirectory/logs
  with 512 KB size-based rotation (current + one backup); never throws.
- FileLoggerProvider: routes ILogger output (incl. Blazor's own Error-level
  log for an unhandled component exception) into the store at Information+.
- Global hooks write to the same store: AndroidEnvironment.UnhandledException-
  Raiser (the reliable .NET-Android catch-all, wired in MainActivity),
  AppDomain.UnhandledException, and TaskScheduler.UnobservedTaskException.
- ILogExporter (Core) abstracts share/export: MauiLogExporter shares the file
  via the OS share sheet; NoopLogExporter (Web) hides the affordance.
- SettingsView gains a Diagnostics → "Export log" button (Android only).
- UI tests register a NoopLogExporter so SettingsView renders resolve.

Web + Android (Debug) build clean; UI bUnit suite 46/46.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HHCRc5CJ6595iMzEgYYdQp
@HarryCordewener
HarryCordewener merged commit c9cb4b4 into master Jun 30, 2026
2 checks passed
@HarryCordewener
HarryCordewener deleted the feat/crash-logging branch June 30, 2026 23:44
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