feat: Copy for a bug report on the launcher's failures, with the launcher's log of what it asked the network #93

Merged
HumanBean merged 2 commits from HumanBean/LongshotLauncher:feat/bug-report into main 2026-11-15 17:21:44 +00:00
Owner

Several players can't reach git.magicbean.dev from the launcher (Longshot#738 and others), and all they can send us is the one sentence on the screen. To find out which request failed, how, and through which proxy, the launcher needs a log and a way to hand it over.

Copy for a bug report now sits beside each of the launcher's failures. It copies what happened, the launcher's version and how it's installed, the system, the network setup (git-cdn first or not, the proxy), and the launcher's log of this run.

What the report looks like

A real one: the update check, run through this branch's code with HTTPS_PROXY pointing at a proxy that doesn't answer:

Longshot Launcher v1.0.0-rc.7 (installed), launcher channel rc, builds from rc
CachyOS, X64, .NET 10.0.15
network: git-cdn.magicbean.dev first, then git.magicbean.dev; proxy: 127.0.0.1:9
what happened: git.magicbean.dev did not answer, so the version to build is not known. This PC is set to go through the proxy 127.0.0.1:9, which did not answer, so git.magicbean.dev was not reached. Check the proxy settings, or turn the proxy off. (Connection refused)

launcher log, its last 7 lines:
04:23:19.510 GET https://git-cdn.magicbean.dev/api/v1/repos/MagicBeanDev/Longshot/releases?limit=50&page=1 failed after 33 ms, through the proxy 127.0.0.1:9: ConnectionError (SocketException: Connection refused)
04:23:19.512 git-cdn.magicbean.dev failed (no answer): trying git.magicbean.dev
04:23:19.513 GET https://git.magicbean.dev/api/v1/repos/MagicBeanDev/Longshot/releases?limit=50&page=1 failed after 0 ms, through the proxy 127.0.0.1:9: ConnectionError (SocketException: Connection refused)
04:23:19.513 GET https://git-cdn.magicbean.dev/api/v1/repos/MagicBeanDev/Longshot/releases?limit=50&page=1 failed after 0 ms, through the proxy 127.0.0.1:9: ConnectionError (SocketException: Connection refused)
04:23:19.513 git-cdn.magicbean.dev failed (no answer): trying git.magicbean.dev
04:23:19.513 GET https://git.magicbean.dev/api/v1/repos/MagicBeanDev/Longshot/releases?limit=50&page=1 failed after 0 ms, through the proxy 127.0.0.1:9: ConnectionError (SocketException: Connection refused)
04:23:19.513 update check failed: This PC is set to go through the proxy 127.0.0.1:9, which did not answer, so git.magicbean.dev was not reached. Check the proxy settings, or turn the proxy off. (Connection refused)

It shows what the screen can't: git-cdn was tried first, then git.magicbean.dev, each twice, all through the proxy, which refused.

What changed

  • Core/LauncherLog.cs: the launcher's log for this run, in memory only (the last 500 lines). Nothing is written to disk.
  • HttpFetcher and CdnFetcher log each request: the link, then the HTTP status (and where it redirected) or why there was no answer (HttpRequestError and .NET's own words), how long it took, and the proxy. Downloads also log their size at the end, or where and why they stopped. The CDN's fall back to git.magicbean.dev is logged too.
  • Core/BugReport.cs: one report format for every screen. The home folder shows as ~ (in any case on Windows, and never a longer folder that only starts like it), so no user name goes with it.
  • The link is on:
    • the update check that failed: on the empty home, and the status line under the versions
    • Home's notices, which is where a failed self-update shows
    • the tools download on step 1, whose message is cut short on its line
    • a game crash: the report includes the crash's signature, which never contains a path
    • a save copy that failed (only a real failure, not "close the game first")
    • the Hookshot saves import and the Hookshot settings import
  • The build-stopped report keeps its contents (the build, the PC, the settings, the build log) and now uses the same format, with the launcher log after it.
  • Failures shown on screen also go into the log (update check results, notices, tools, saves, Hookshot imports), so a report made later still has them.
  • The new toast is translated in all 12 full catalogs.

No game file, key or save goes into a report: only what the screens say, links, and paths with the home folder as ~. The report only goes to the clipboard, and the player decides where to paste it.

Screenshots

Drawn with tools/screenshots, which has a scene for each of these now. They are in the comment below.

tools/screenshots didn't compile on main (LauncherService.Gpus became read-only when GpuCards came in, and CI doesn't build the tool). Its three scenes that set a GPU now set GpuCards. Step 1 also gets a search: false switch, so a screenshot never lists game files from the PC it's drawn on. The failed save copy has no scene: it needs a whole saves setup.

Testing

  • python -I tests/test_launcher_core.py: 1175 checks pass. The new ReportChecks.cs checks:
    • the log: stamped lines, the last 500 kept, one line each
    • the report's parts and their order
    • home-folder scrubbing on Windows and Linux, and that a folder which only starts like the home folder stays as it is
    • a refused request logged with why (https://127.0.0.1:1, offline)
    • the CDN's fall back logged
  • python -I tests/test_release.py: 29 tests pass.
  • dotnet build App -c Release -p:RestoreLockedMode=true -warnaserror and tools/screenshots build.
  • Ran the update check through the new Core against the live servers (the log has each list and SHA256SUMS request with its status and time), and through a dead proxy (the report above).

🤖 Generated with Claude Code

Several players can't reach git.magicbean.dev from the launcher (Longshot#738 and others), and all they can send us is the one sentence on the screen. To find out which request failed, how, and through which proxy, the launcher needs a log and a way to hand it over. **Copy for a bug report** now sits beside each of the launcher's failures. It copies what happened, the launcher's version and how it's installed, the system, the network setup (git-cdn first or not, the proxy), and the launcher's log of this run. ## What the report looks like A real one: the update check, run through this branch's code with `HTTPS_PROXY` pointing at a proxy that doesn't answer: ``` Longshot Launcher v1.0.0-rc.7 (installed), launcher channel rc, builds from rc CachyOS, X64, .NET 10.0.15 network: git-cdn.magicbean.dev first, then git.magicbean.dev; proxy: 127.0.0.1:9 what happened: git.magicbean.dev did not answer, so the version to build is not known. This PC is set to go through the proxy 127.0.0.1:9, which did not answer, so git.magicbean.dev was not reached. Check the proxy settings, or turn the proxy off. (Connection refused) launcher log, its last 7 lines: 04:23:19.510 GET https://git-cdn.magicbean.dev/api/v1/repos/MagicBeanDev/Longshot/releases?limit=50&page=1 failed after 33 ms, through the proxy 127.0.0.1:9: ConnectionError (SocketException: Connection refused) 04:23:19.512 git-cdn.magicbean.dev failed (no answer): trying git.magicbean.dev 04:23:19.513 GET https://git.magicbean.dev/api/v1/repos/MagicBeanDev/Longshot/releases?limit=50&page=1 failed after 0 ms, through the proxy 127.0.0.1:9: ConnectionError (SocketException: Connection refused) 04:23:19.513 GET https://git-cdn.magicbean.dev/api/v1/repos/MagicBeanDev/Longshot/releases?limit=50&page=1 failed after 0 ms, through the proxy 127.0.0.1:9: ConnectionError (SocketException: Connection refused) 04:23:19.513 git-cdn.magicbean.dev failed (no answer): trying git.magicbean.dev 04:23:19.513 GET https://git.magicbean.dev/api/v1/repos/MagicBeanDev/Longshot/releases?limit=50&page=1 failed after 0 ms, through the proxy 127.0.0.1:9: ConnectionError (SocketException: Connection refused) 04:23:19.513 update check failed: This PC is set to go through the proxy 127.0.0.1:9, which did not answer, so git.magicbean.dev was not reached. Check the proxy settings, or turn the proxy off. (Connection refused) ``` It shows what the screen can't: git-cdn was tried first, then git.magicbean.dev, each twice, all through the proxy, which refused. ## What changed - **`Core/LauncherLog.cs`**: the launcher's log for this run, in memory only (the last 500 lines). Nothing is written to disk. - **`HttpFetcher` and `CdnFetcher`** log each request: the link, then the HTTP status (and where it redirected) or why there was no answer (`HttpRequestError` and .NET's own words), how long it took, and the proxy. Downloads also log their size at the end, or where and why they stopped. The CDN's fall back to git.magicbean.dev is logged too. - **`Core/BugReport.cs`**: one report format for every screen. The home folder shows as `~` (in any case on Windows, and never a longer folder that only starts like it), so no user name goes with it. - **The link** is on: - the update check that failed: on the empty home, and the status line under the versions - Home's notices, which is where a failed self-update shows - the tools download on step 1, whose message is cut short on its line - a game crash: the report includes the crash's signature, which never contains a path - a save copy that failed (only a real failure, not "close the game first") - the Hookshot saves import and the Hookshot settings import - The **build-stopped** report keeps its contents (the build, the PC, the settings, the build log) and now uses the same format, with the launcher log after it. - Failures shown on screen also go into the log (update check results, notices, tools, saves, Hookshot imports), so a report made later still has them. - The new toast is translated in all 12 full catalogs. No game file, key or save goes into a report: only what the screens say, links, and paths with the home folder as `~`. The report only goes to the clipboard, and the player decides where to paste it. ## Screenshots Drawn with `tools/screenshots`, which has a scene for each of these now. They are in the comment below. `tools/screenshots` didn't compile on main (`LauncherService.Gpus` became read-only when `GpuCards` came in, and CI doesn't build the tool). Its three scenes that set a GPU now set `GpuCards`. Step 1 also gets a `search: false` switch, so a screenshot never lists game files from the PC it's drawn on. The failed save copy has no scene: it needs a whole saves setup. ## Testing - `python -I tests/test_launcher_core.py`: 1175 checks pass. The new `ReportChecks.cs` checks: - the log: stamped lines, the last 500 kept, one line each - the report's parts and their order - home-folder scrubbing on Windows and Linux, and that a folder which only starts like the home folder stays as it is - a refused request logged with why (`https://127.0.0.1:1`, offline) - the CDN's fall back logged - `python -I tests/test_release.py`: 29 tests pass. - `dotnet build App -c Release -p:RestoreLockedMode=true -warnaserror` and `tools/screenshots` build. - Ran the update check through the new Core against the live servers (the log has each list and `SHA256SUMS` request with its status and time), and through a dead proxy (the report above). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat: Copy for a bug report on the launcher's failures, with the launcher's log of what it asked the network
All checks were successful
CI / Compile and test (pull_request) Has been skipped
CI / Conventional Commit title (pull_request) Successful in 3s
5d17d4b925
Players who can't reach git.magicbean.dev (issue Longshot#738 and others) can only
tell us one sentence. A Copy for a bug report link on each failure now copies what
happened, the launcher's version, the system, the proxy and git-cdn setting, and
the launcher's log of this run: every request with its answer or why there was
none, the CDN's fall back, and the failures shown.

- Core/LauncherLog.cs: the run's log, in memory only (500 lines)
- Core/BugReport.cs: the report; the home folder as ~
- HttpFetcher and CdnFetcher log each request; the build-stopped report carries the
  launcher log too
- the link on: the update check (empty home and the status line), Home's notices
  (the launcher's own update), the tools' download, a game crash, a failed save
  copy, and the Hookshot saves and settings imports
- tools/screenshots: scenes for these, and builds again (GpuCards)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Author
Owner

Screenshots, drawn with tools/screenshots (each scene's name in brackets):

The update check failed, on the empty home (home-check-failed)
home-check-failed

A notice on Home: the launcher's own update failed (home-notice)
home-notice

Step 1, the tools' download failed (tools-failed)
tools-failed

The game closed unexpectedly (crash)
crash

Importing Hookshot's saves failed (hookshot-import-problem)
hookshot-import-problem

Screenshots, drawn with `tools/screenshots` (each scene's name in brackets): **The update check failed, on the empty home** (`home-check-failed`) ![home-check-failed](https://git.magicbean.dev/attachments/ee9bcb26-b388-47eb-abb1-f273cb497cca) **A notice on Home: the launcher's own update failed** (`home-notice`) ![home-notice](https://git.magicbean.dev/attachments/0ddf6e1a-88b5-4de7-9efb-911712698e85) **Step 1, the tools' download failed** (`tools-failed`) ![tools-failed](https://git.magicbean.dev/attachments/ee490665-be49-44e8-9c10-46e6e048353e) **The game closed unexpectedly** (`crash`) ![crash](https://git.magicbean.dev/attachments/ab7ed76f-2b8e-4d99-b427-787bbca16051) **Importing Hookshot's saves failed** (`hookshot-import-problem`) ![hookshot-import-problem](https://git.magicbean.dev/attachments/b494abf7-d6c9-46cc-8dc2-accb5d405397)
futondestroyer left a comment

Reviewed head 5d17d4b925. The shared report formatter, bounded in-memory log and explicit clipboard action are useful for diagnosing the current network failures. The original build report's useful context is retained, and the screenshot search opt-out avoids discovering real game files for illustrations.

One required fix: the new home-path redactor does not handle Windows paths using forward slashes and does not enforce a directory-component boundary. See the inline comment for reproducible synthetic examples. These reports are intended for sharing; the stated username scrubbing needs to cover the path forms that diagnostics can contain.

Independent Windows validation, .NET SDK 10.0.401:

  • Release app build with locked restore and warnings as errors: passes, zero warnings/errors.
  • Core checks: 1,151 passed. Successful symlink cases are explicitly skipped because this Windows session lacks the privilege; this is not the author's complete Linux coverage. No cross-repository --longshot checks were requested in this run.
  • Release checks: 29/29 passed with the installed OpenSSL on PATH.
  • A separate tiny console referencing the actual built Core assembly reproduced the redaction examples and confirmed that BugReport.Make retains the synthetic forward-slash username. No real personal paths or game files were used in that reproduction.
  • git diff --check passes.

Environment notes: the first core invocation incorrectly requested --strict without its required --longshot argument and did not execute the suite. After that was corrected, the suite stopped at signature verification because this PC's Git autocrlf converted the signed SHA256SUMS fixture to CRLF. Running with its exact committed bytes passed; no signature check or test assertion was weakened. The first release invocation lacked OpenSSL on PATH; the corrected run above passed. The isolated checkout was left clean after testing.

Not tested: Linux execution, a live Launcher window or clipboard interaction, the screenshot tool build, real save import/build failures, or live service/proxy failures. No game, real save transfer, release or deployment was run.

Reviewed head 5d17d4b925c3ad2df203ef84cdc98692021ddc4f. The shared report formatter, bounded in-memory log and explicit clipboard action are useful for diagnosing the current network failures. The original build report's useful context is retained, and the screenshot search opt-out avoids discovering real game files for illustrations. One required fix: the new home-path redactor does not handle Windows paths using forward slashes and does not enforce a directory-component boundary. See the inline comment for reproducible synthetic examples. These reports are intended for sharing; the stated username scrubbing needs to cover the path forms that diagnostics can contain. Independent Windows validation, .NET SDK 10.0.401: - Release app build with locked restore and warnings as errors: passes, zero warnings/errors. - Core checks: 1,151 passed. Successful symlink cases are explicitly skipped because this Windows session lacks the privilege; this is not the author's complete Linux coverage. No cross-repository --longshot checks were requested in this run. - Release checks: 29/29 passed with the installed OpenSSL on PATH. - A separate tiny console referencing the actual built Core assembly reproduced the redaction examples and confirmed that BugReport.Make retains the synthetic forward-slash username. No real personal paths or game files were used in that reproduction. - git diff --check passes. Environment notes: the first core invocation incorrectly requested --strict without its required --longshot argument and did not execute the suite. After that was corrected, the suite stopped at signature verification because this PC's Git autocrlf converted the signed SHA256SUMS fixture to CRLF. Running with its exact committed bytes passed; no signature check or test assertion was weakened. The first release invocation lacked OpenSSL on PATH; the corrected run above passed. The isolated checkout was left clean after testing. Not tested: Linux execution, a live Launcher window or clipboard interaction, the screenshot tool build, real save import/build failures, or live service/proxy failures. No game, real save transfer, release or deployment was run.
@ -0,0 +52,4 @@
var h = home?.TrimEnd('/', '\\');
if (string.IsNullOrEmpty(h) || h.Length <= 3) return text;
var windows = h.Contains('\\') || (h.Length > 1 && h[1] == ':');
return Regex.Replace(text, Regex.Escape(h) + @"(?![\w.-])", "~", windows ? RegexOptions.IgnoreCase : RegexOptions.None);
Member

[P2] Match Windows separator variants and a complete home-directory component before copying the report. Against the actual built Core assembly, Scrub("C:/Users/Pat/work/build.log", @"C:\Users\Pat") returns the original string, and BugReport.Make retains that username in its copied build-log section; file:///C:/Users/Pat/... is likewise unchanged. Windows diagnostic paths can use forward slashes even though SpecialFolder.UserProfile supplies backslashes. The current negative lookahead also treats a space as a boundary, so @"C:\Users\Pat Smith\work\build.log" becomes @"~ Smith\work\build.log" even though it is a different home directory, contrary to the documented prefix rule. Please recognize both separators on Windows and replace only the exact home component (separator/end or an appropriate path terminator), with regressions for forward-slash/file-URI input and a longer sibling containing a space.

[P2] Match Windows separator variants and a complete home-directory component before copying the report. Against the actual built Core assembly, Scrub("C:/Users/Pat/work/build.log", @"C:\Users\Pat") returns the original string, and BugReport.Make retains that username in its copied build-log section; file:///C:/Users/Pat/... is likewise unchanged. Windows diagnostic paths can use forward slashes even though SpecialFolder.UserProfile supplies backslashes. The current negative lookahead also treats a space as a boundary, so @"C:\Users\Pat Smith\work\build.log" becomes @"~ Smith\work\build.log" even though it is a different home directory, contrary to the documented prefix rule. Please recognize both separators on Windows and replace only the exact home component (separator/end or an appropriate path terminator), with regressions for forward-slash/file-URI input and a longer sibling containing a space.
Contributor

A fix for futondestroyer's [P2] (the home-folder scrub), one commit on top of this branch's head 5d17d4b: madebyjordan/LongshotLauncher@5b9ca21b0f, branch fix/pr93-scrub on my fork. Maintainer edits are off here, so I couldn't push it to the PR. To take it:

git fetch https://git.magicbean.dev/madebyjordan/LongshotLauncher.git fix/pr93-scrub
git cherry-pick 5b9ca21

What changes in BugReport.Scrub:

  • On Windows, each separator of the home folder matches \ or /, also doubled (JSON-escaped). So C:/Users/Pat/work/build.log becomes ~/work/build.log and file:///C:/Users/Pat/x becomes file:///~/x.

  • A space in the home folder also matches %20, for file:// links.

  • The home folder only matches as a whole folder. It must be followed by:

    • a separator, a line end or the end of the text;
    • a quote, a bracket, , ; :;
    • a sentence's full stop;
    • or a space or tab whose next word isn't a path.

    So C:\Users\Pat Smith\work\build.log, Pat-x, Pat2, Pat.old and Pat%20Smith stay as they are. 'C:\Users\Pat' is denied, Saved in C:\Users\Pat., C:\Users\Pat is full and (C:\Users\Pat) become ~.

One edge left. A sibling folder with two or more spaces before its next separator (C:\Users\Pat Smith Jr\x) still reads as the home folder followed by prose, so it becomes ~ Smith Jr\x. It now errs toward hiding the name rather than leaving it.

New checks in ReportChecks.cs:

  • forward slashes, a file:/// link, doubled separators, mixed case;
  • the Pat Smith, Pat%20Smith and Pat-x siblings;
  • a home folder with a space;
  • the home folder in prose, quotes and brackets, and before a line holding another path;
  • BugReport.Make with a forward-slash path naming no user.

Tested on Windows 11, .NET SDK 10.0.404: python -I tests/test_launcher_core.py passes 1158 checks (the symlink success fixtures are skipped without the privilege, as in the review). With the PR's original BugReport.cs and the new checks, it fails on C:/Users/Pat/work/build.log.

Two Windows notes for whoever runs the checks:

  • With core.autocrlf=true the signed SHA256SUMS fixture checks out as CRLF. Re-check tests/fixtures/release out with -c core.autocrlf=false.
  • With %TEMP% as an 8.3 short path (JORDAN~1.DES), the portable-home check in InstallChecks.cs:181 fails, because Path.GetFullPath expands the short name. Both happen on main too; neither is from this PR.
A fix for futondestroyer's [P2] (the home-folder scrub), one commit on top of this branch's head 5d17d4b: madebyjordan/LongshotLauncher@5b9ca21b0f7700d8362486a757af475069bd601e, branch `fix/pr93-scrub` on my fork. Maintainer edits are off here, so I couldn't push it to the PR. To take it: ``` git fetch https://git.magicbean.dev/madebyjordan/LongshotLauncher.git fix/pr93-scrub git cherry-pick 5b9ca21 ``` **What changes in `BugReport.Scrub`:** - On Windows, each separator of the home folder matches `\` or `/`, also doubled (JSON-escaped). So `C:/Users/Pat/work/build.log` becomes `~/work/build.log` and `file:///C:/Users/Pat/x` becomes `file:///~/x`. - A space in the home folder also matches `%20`, for `file://` links. - The home folder only matches as a whole folder. It must be followed by: - a separator, a line end or the end of the text; - a quote, a bracket, `,` `;` `:`; - a sentence's full stop; - or a space or tab whose next word isn't a path. So `C:\Users\Pat Smith\work\build.log`, `Pat-x`, `Pat2`, `Pat.old` and `Pat%20Smith` stay as they are. `'C:\Users\Pat' is denied`, `Saved in C:\Users\Pat.`, `C:\Users\Pat is full` and `(C:\Users\Pat)` become `~`. **One edge left.** A sibling folder with two or more spaces before its next separator (`C:\Users\Pat Smith Jr\x`) still reads as the home folder followed by prose, so it becomes `~ Smith Jr\x`. It now errs toward hiding the name rather than leaving it. **New checks in `ReportChecks.cs`:** - forward slashes, a `file:///` link, doubled separators, mixed case; - the `Pat Smith`, `Pat%20Smith` and `Pat-x` siblings; - a home folder with a space; - the home folder in prose, quotes and brackets, and before a line holding another path; - `BugReport.Make` with a forward-slash path naming no user. **Tested on Windows 11, .NET SDK 10.0.404:** `python -I tests/test_launcher_core.py` passes 1158 checks (the symlink success fixtures are skipped without the privilege, as in the review). With the PR's original `BugReport.cs` and the new checks, it fails on `C:/Users/Pat/work/build.log`. Two Windows notes for whoever runs the checks: - With `core.autocrlf=true` the signed `SHA256SUMS` fixture checks out as CRLF. Re-check `tests/fixtures/release` out with `-c core.autocrlf=false`. - With `%TEMP%` as an 8.3 short path (`JORDAN~1.DES`), the portable-home check in `InstallChecks.cs:181` fails, because `Path.GetFullPath` expands the short name. Both happen on main too; neither is from this PR.
fix(report): the home folder scrubbed with either Windows separator, and only as a whole folder
All checks were successful
CI / Compile and test (pull_request) Has been skipped
CI / Conventional Commit title (pull_request) Successful in 5s
5b9ca21b0f
futondestroyer's review of #93: C:/Users/Pat/work/build.log and file:///C:/Users/Pat/... kept the
user name, and C:\Users\Pat Smith\x became ~ Smith\x.

Scrub now matches either separator on Windows (also doubled, as JSON writes it), a space in the
home folder also as %20, and the home folder only where its last name ends: a separator, the
line's end, a quote or bracket, a sentence's full stop, or a space whose next word is no path.
C:\Users\Pat Smith\x, Pat-x, Pat2, Pat.old and Pat%20Smith stay as they are.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
HumanBean deleted branch feat/bug-report 2026-11-15 17:21:44 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
3 participants
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!93
No description provided.