feat(crash): the crash window, --crash <folder> #46

Open
gab9281 wants to merge 3 commits from gab9281/LongshotLauncher:feat/crash-window into main
Member

After a crash, Longshot should show the player the crash report and send it only when they say so. The windows that did this in Longshot #141 lived in the builders, which main has removed (#171, #181). The game already starts its folder's builder=, which is this launcher, so the window moves here.

What changed

  • --crash <folder> (Core/CommandLine.cs, App/Program.cs, App/App.axaml.cs): only the crash window opens. There is no instance lock, so it runs beside an open launcher, and no update check. A crash whose window never opened (the launcher moved, or the game was killed first) is offered at the launcher's next start, over its window.
  • Core/CrashReports.cs: the report itself stays in Longshot, in nx2/crash_report.py (its fields, the redaction, the limits, the send). It runs with the folder's version's Python, or else the newest installed tools that have the script:
    • --window returns what to show, as one line of JSON, and sends nothing;
    • --send --json --time <t> runs after Send Help. It is a process of its own, so the window can close during a slow send and the send still finishes. The report is kept unless it was sent or refused.
    • I am sorry drops only that crash's marker. The Always send crash reports tick is longshot_crash.ini in the folder, as the script reads it.
  • App/CrashWindow.cs: the window, built in code like SetupWindows. It has the report's rows, a Show for the settings and the log, Send Help / I am sorry, the Sent page with the link to the report's comment, and the two beans (App/Assets/crash-bean.png, magicbean-report-sent.png, Magic Bean's own art).
  • README: an "After a crash" paragraph and --crash in the command-line table.

Testing

Tested (CachyOS, KDE Wayland and XWayland, .NET 10.0.114):

  • dotnet build LongshotLauncher.slnx -c Release -p:RestoreLockedMode=true: 0 errors. The one warning (TextBox.Watermark) is on main too.
  • tests/test_launcher_core.py --strict --longshot <Longshot checkout>: 704 checks passed, 30 of them new (tests/launcher_core/CrashChecks.cs). They cover --crash, which tools read the report, the two commands and their answers, the marker, and the tick. tests/test_release.py: OK.
  • A real crash, end to end: OoT built from Longshot #141 @ 25ee9472 into a folder whose builder= is this launcher (RTX 3060 Laptop, NVIDIA 620.70.06, CachyOS, KDE Wayland). kill -SEGV at 25 s had --crash running 0.11 s later, with no signal blocked and none of the game's files open, and the window showed the real report (Longshot #141's screenshot).
  • --crash on a made-up game folder (the crash log from Longshot's tests), with tools whose nx2/crash_report.py is #141's: the window reads and shows the report (screenshot). The send command, run as the window runs it against a stand-in relay on 127.0.0.1, posted the report and dropped the marker.

Not tested:

  • Clicking through Send Help and the Sent page on screen. Being checked by hand now; the result will go in a comment.
  • Windows.

Needs other testers:

  • Windows 10/11: a crash in a build made with #141 opens this window, and Send Help posts to Longshot #81. Request to open once #141 is merged.

Screenshots

This PR @ a0873ef1, --crash on a made-up crash (nothing on main: --crash is ignored there and opens the launcher):

the crash window

Review

A /code-review (high) found 10 things, all fixed in ff11da5:

  • One window per crash (crash_window.lock): a second --crash, or the launcher's start, leaves a crash that has a window alone, so one report can't be sent twice.
  • The start offers only a real report: the build's tools can read it, and --window answered with one. It goes on to the next build otherwise.
  • Closing before an answer is I am sorry, even while the report is still being read. Tools that can't read it keep it until the build is updated.
  • JSON: a value of any kind is read as text, never thrown.
  • The tick is put back, with the reason, when it can't be saved.
  • --crash builds only the toolchains.
  • Environment: the tools run in GamePlay.Environment.
  • Arguments: --crash /a --launch /b keeps /a.

Since then, 86f79d2: the window shows the script's reason when the report can't be made.

Depends on

MagicBeanDev/Longshot#141 (--window and --send --json in nx2/crash_report.py, and the game starting --crash). Until a builder carries it, the window says "This build's tools can't read crash reports yet" and the crash stays in the log.

🤖 Generated with Claude Code

https://claude.ai/code/session_015KgSKoUqUvce5UXG89NBgi

After a crash, Longshot should show the player the crash report and send it only when they say so. The windows that did this in Longshot #141 lived in the builders, which main has removed (#171, #181). The game already starts its folder's `builder=`, which is this launcher, so the window moves here. ## What changed - **`--crash <folder>`** (`Core/CommandLine.cs`, `App/Program.cs`, `App/App.axaml.cs`): only the crash window opens. There is no instance lock, so it runs beside an open launcher, and no update check. A crash whose window never opened (the launcher moved, or the game was killed first) is offered at the launcher's next start, over its window. - **`Core/CrashReports.cs`**: the report itself stays in Longshot, in `nx2/crash_report.py` (its fields, the redaction, the limits, the send). It runs with the folder's version's Python, or else the newest installed tools that have the script: - `--window` returns what to show, as one line of JSON, and sends nothing; - `--send --json --time <t>` runs after Send Help. It is a process of its own, so the window can close during a slow send and the send still finishes. The report is kept unless it was sent or refused. - I am sorry drops only that crash's marker. The *Always send crash reports* tick is `longshot_crash.ini` in the folder, as the script reads it. - **`App/CrashWindow.cs`**: the window, built in code like `SetupWindows`. It has the report's rows, a Show for the settings and the log, Send Help / I am sorry, the Sent page with the link to the report's comment, and the two beans (`App/Assets/crash-bean.png`, `magicbean-report-sent.png`, Magic Bean's own art). - **README**: an "After a crash" paragraph and `--crash` in the command-line table. ## Testing **Tested** (CachyOS, KDE Wayland and XWayland, .NET 10.0.114): - `dotnet build LongshotLauncher.slnx -c Release -p:RestoreLockedMode=true`: 0 errors. The one warning (`TextBox.Watermark`) is on main too. - `tests/test_launcher_core.py --strict --longshot <Longshot checkout>`: 704 checks passed, 30 of them new (`tests/launcher_core/CrashChecks.cs`). They cover `--crash`, which tools read the report, the two commands and their answers, the marker, and the tick. `tests/test_release.py`: OK. - A real crash, end to end: OoT built from Longshot #141 @ 25ee9472 into a folder whose `builder=` is this launcher (RTX 3060 Laptop, NVIDIA 620.70.06, CachyOS, KDE Wayland). `kill -SEGV` at 25 s had `--crash` running 0.11 s later, with no signal blocked and none of the game's files open, and the window showed the real report (Longshot #141's screenshot). - `--crash` on a made-up game folder (the crash log from Longshot's tests), with tools whose `nx2/crash_report.py` is #141's: the window reads and shows the report (screenshot). The send command, run as the window runs it against a stand-in relay on 127.0.0.1, posted the report and dropped the marker. **Not tested:** - Clicking through Send Help and the Sent page on screen. Being checked by hand now; the result will go in a comment. - Windows. **Needs other testers:** - Windows 10/11: a crash in a build made with #141 opens this window, and Send Help posts to Longshot #81. Request to open once #141 is merged. ## Screenshots This PR @ a0873ef1, `--crash` on a made-up crash (nothing on main: `--crash` is ignored there and opens the launcher): ![the crash window](https://git.magicbean.dev/attachments/76e8057e-4a56-4702-bb25-1931d79243b0) ## Review A `/code-review` (high) found 10 things, all fixed in ff11da5: - **One window per crash** (`crash_window.lock`): a second `--crash`, or the launcher's start, leaves a crash that has a window alone, so one report can't be sent twice. - **The start offers only a real report:** the build's tools can read it, and `--window` answered with one. It goes on to the next build otherwise. - **Closing before an answer is I am sorry,** even while the report is still being read. Tools that can't read it keep it until the build is updated. - **JSON:** a value of any kind is read as text, never thrown. - **The tick** is put back, with the reason, when it can't be saved. - **`--crash`** builds only the toolchains. - **Environment:** the tools run in `GamePlay.Environment`. - **Arguments:** `--crash /a --launch /b` keeps `/a`. Since then, 86f79d2: the window shows the script's reason when the report can't be made. ## Depends on MagicBeanDev/Longshot#141 (`--window` and `--send --json` in `nx2/crash_report.py`, and the game starting `--crash`). Until a builder carries it, the window says "This build's tools can't read crash reports yet" and the crash stays in the log. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_015KgSKoUqUvce5UXG89NBgi
feat(crash): the crash window, --crash <folder>
All checks were successful
CI / Compile and test (pull_request) Has been skipped
CI / Conventional Commit title (pull_request) Successful in 18s
a0873ef17c
After a crash the game starts its folder's builder= (this launcher) with
--crash <folder> (Longshot's host/hos_crash_window.c). The window shows
everything the report holds, and sends it only on Send Help, to
Longshot's crash issue; I am sorry sends nothing.

- Core/CrashReports.cs: the report is Longshot's nx2/crash_report.py,
  run with the folder's version's Python (or the newest installed tools
  that have it): --window for what to show, nothing sent; --send --json
  after Send Help. The send is a process of its own, so the window can
  close during a slow send and the send finishes; the report is kept
  unless it went or was refused. I am sorry drops only that crash's
  marker; the Always send tick is longshot_crash.ini in the folder.
- App/CrashWindow.cs: the window, in code as SetupWindows, with the two
  beans (Magic Bean's own art, from Longshot #141).
- --crash runs without the instance lock (beside an open launcher); a
  crash whose window never opened is offered at the launcher's start.
- tests: CrashChecks (22 checks).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015KgSKoUqUvce5UXG89NBgi
fix(crash): the review's findings on the crash window
All checks were successful
CI / Compile and test (pull_request) Has been skipped
CI / Conventional Commit title (pull_request) Successful in 2s
ff11da587e
- One window per crash: CrashReports.Hold (crash_window.lock, held
  alone); a second --crash, or the launcher's start, leaves a crash that
  has a window. No more two sends of one report.
- The start offers a crash only when its tools read it and --window
  answers with a report (no window for an empty marker), and goes on to
  the next build otherwise.
- Closing before an answer is I am sorry even while --window still reads
  (the marker's time read at open); tools that can't read the report
  keep it until the build is updated.
- ReadWindow/ReadSend read values of any JSON kind as text, never throw.
- The tick is put back, with the reason, when it can't be saved, and
  starts from the script's answer.
- --crash builds only the toolchains, not a LauncherService.
- The tools run in GamePlay.Environment (no LD_LIBRARY_PATH or AppImage
  runtime), not a second list.
- --crash /a --launch /b keeps /a.
- No Ui.Post after awaits that are on the UI thread already.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015KgSKoUqUvce5UXG89NBgi
fix(crash): the window says why the report couldn't be made
All checks were successful
CI / Compile and test (pull_request) Has been skipped
CI / Conventional Commit title (pull_request) Successful in 3s
86f79d241c
crash_report.py --window answers {"crash": false, "error": ...} when the report
can't be made (Longshot #141's review); the window shows that reason.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015KgSKoUqUvce5UXG89NBgi
gab9281 changed title from WIP: feat(crash): the crash window, --crash <folder> to feat(crash): the crash window, --crash <folder> 2026-11-13 17:57:04 +00:00
All checks were successful
CI / Compile and test (pull_request) Has been skipped
CI / Conventional Commit title (pull_request) Successful in 3s
This pull request doesn't have enough approvals yet. 0 of 1 approvals granted.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u 'feat/crash-window:gab9281-feat/crash-window'
git switch 'gab9281-feat/crash-window'
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
MagicBeanDev/LongshotLauncher!46
No description provided.