Skip to content

feat: add export-logs-as-file option to startup error screen - #2490

Open
i5hi wants to merge 1 commit into
mainfrom
log-to-file-startup
Open

feat: add export-logs-as-file option to startup error screen#2490
i5hi wants to merge 1 commit into
mainfrom
log-to-file-startup

Conversation

@i5hi

@i5hi i5hi commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a "download logs as a file" (export) button to the app startup error screen, alongside the existing "share logs" button — lets a user stuck on the startup error screen save their logs to a file (via the OS file picker) instead of only being able to share them.

This is extracted from #2438 and #2440 (both still open, larger PIN-error-handling and LWK-concurrent-wollet-access work) so this standalone log-export improvement can ship independently without waiting on that larger work. It does not touch any PIN/keychain/LWK logic.

Files changed (3)

  • lib/core/screens/app_init_error_screen.dart
  • lib/core/widgets/share_logs_bottom_sheet.dart
  • lib/core/widgets/share_logs_widget.dart

No new localization strings are needed — all loc keys used (logsExportedMessage, logsExportFailedMessage, logsShareOptionExport, errorSharingLogsMessage) already exist on main, added by an earlier merged PR (#2317).

Test plan

  • fvm dart analyze clean on the 3 changed files
  • fvm dart format clean on the 3 changed files
  • Confirmed no existing test files reference these 3 widgets (grepped test/)
  • Pre-commit hook (project-wide analyze) passed

🤖 Generated with Claude Code

Lets a user stuck on the app startup error screen save their logs to a
file via the OS file picker, instead of only being able to share them.

Extracted from #2438 and #2440 so this standalone log-export
improvement can ship independently of the larger PIN/LWK-concurrency
work in those PRs.
@ethicnology

Copy link
Copy Markdown
Member

@claude review

@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown

Claude finished @ethicnology's task in 2m 32s —— View job


PR Review: export-logs-as-file on startup error screen

  • Read repo guidelines (no CLAUDE.md found in this repo)
  • Examine the diff against origin/main
  • Read the 3 changed files in full context
  • Verify localization keys exist on main
  • Post review feedback

Overall this is a clean, well-scoped change and the core logic is correct — mounted checks are placed properly around the async gaps, errors are caught and surfaced with localized messages, and I verified all four loc keys (errorSharingLogsMessage, logsShareOptionExport, logsExportedMessage, logsExportFailedMessage) already exist in localization/app_en.arb. A few findings, ordered by importance:

1. Shared log files are written to the temp dir and never deleted

shareLogsAsFile (lib/core/widgets/share_logs_bottom_sheet.dart:64-73) writes the logs to a timestamped file in the temporary directory and shares it, but never removes it. Because the filename is unique per call, every share leaves another copy of the full logs on disk. The OS clears the temp dir only opportunistically, so in a bitcoin wallet app this means log data (which readLogs merges from both isolates and can include error details) accumulates outside the app's managed log file. Since SharePlus.instance.share completes when the share sheet resolves, you can delete the file afterwards:

final file = File(path);
await file.writeAsString(logs.join('\n'));
try {
  await SharePlus.instance.share(
    ShareParams(files: [XFile(path)], subject: 'bull_logs.tsv'),
  );
} finally {
  await file.delete();
}

(One caveat: on some Android targets the receiving app reads the file after the sheet returns, so if you've seen that bite before, an alternative is a fixed filename so at most one stale copy ever exists.) Fix this →

2. The PR changes more behavior than the description states

The description says this only adds an export button to the startup error screen, but lib/core/widgets/share_logs_widget.dart (the settings logs widget) also changes behavior in two ways:

  • "Share logs" no longer opens the showLogsShareSheet chooser — it now shares directly, and a second "Export" tile was added.
  • Sharing switched from text (shareLogsAsText) to a file attachment (shareLogsAsFile).

Both are defensible (file attachments avoid Android intent size limits on large logs), but note that lib/core/widgets/log_viewer_widget.dart:95-112 still uses the old bottom sheet + shareLogsAsText, so the log viewer and the settings widget now behave differently for the same "share logs" action. Worth either aligning the log viewer in a follow-up or stating in the description that this divergence is intentional. Either way, please update the PR description to mention the settings-widget behavior change.

3. Minor: share subject doesn't match the attached filename

shareLogsAsFile sets subject: 'bull_logs.tsv' while the attached file is bull_logs_<timestamp>.tsv. Cosmetic, but easy to align by reusing the generated name.

Notes

  • No dead code introduced: showLogsShareSheet and shareLogsAsText are still used by log_viewer_widget.dart.
  • Calling log.severe/log.readLogs on the pre-init error screen is safe — the global logger is eagerly seeded with a placeholder (lib/core/utils/logger.dart:19), and the record listener swallows its own failures.
  • The startup screen's error snackbar moving from a hardcoded English string to loc.errorSharingLogsMessage is a nice cleanup.
  • I could not run dart analyze/dart format — no Flutter/Dart toolchain is installed on this runner, so I'm relying on the author's stated checks and CI.

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.

2 participants