fix: splash hangs forever on "Loading Cargo Data" when a cargo download fails#127
Open
raman78 wants to merge 1 commit into
Open
fix: splash hangs forever on "Loading Cargo Data" when a cargo download fails#127raman78 wants to merge 1 commit into
raman78 wants to merge 1 commit into
Conversation
…ad fails Three small, related issues conspire to freeze the splash screen on the "Loading Cargo Data..." step when any cargo table fails to download: - get_cargo_data falls through to an implicit None when the network download fails and no backup exists (typical on a fresh install), causing the caller to TypeError while iterating None. - Downloader.fetch_json only catches Timeout/JSONDecodeError, so other requests failures (ConnectionError, SSLError, ChunkedEncodingError, Cloudflare-style malformed responses) propagate uncaught. - widgets.Thread.run does not catch exceptions from its target, so any failure above prevents the `done` signal from ever firing — the splash stays on "Loading Cargo Data..." with no error shown. Fix all three so a cargo failure becomes a real, attributable error instead of a permanent freeze.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On a fresh install (and occasionally on updates), the splash screen gets stuck on "Loading Cargo Data..." with no error and no progress. Users have reported this on Discord — the workaround so far has been to hand-copy somebody else's
cargo/*.jsonfiles, which masks the real bug.The freeze is not a slow download. It's three small issues in the cargo loading path that combine into one silent hang.
Root cause
CargoManager.get_cargo_datacan silently returnNone.When the wiki download fails and the GitHub cache fallback fails and there are no local backup files (the situation on every fresh install), the function falls through the
# TODO what happens when both backups fail?branch without areturn. Callers likecache_boff_datathen dofor boff_ability in boff_cargo:and crash withTypeError: 'NoneType' is not iterable.Downloader.fetch_jsononly catchesTimeoutandJSONDecodeError.Anything else
requestscan raise —ConnectionError,SSLError,ChunkedEncodingError, Cloudflare returning a 5xx with a malformed body, etc. — propagates straight up.widgets.Thread.rundoesn't catch exceptions from its target.init_backendruns inside thisQThread. If the target raises (because of 1 or 2),self.done.emit()is never reached.complete_app_initis wired todone, so it never runs and the splash stays on "Loading Cargo Data..." forever, with no error in the UI.The reason it tends to hit later cargo tables (boff abilities, doffs, modifiers) is just that those queries are larger/slower on the wiki and so more prone to timing out or being rate-limited. Once one fails, the whole splash freezes.
Fix
Three minimal changes, one per file:
src/cargomanager.py— replace the TODO with a real error so the caller can surface it instead of crashing onNone:src/downloader.py— widen the exception net to allrequestsfailures:src/widgets.py— makeThreademitdoneeven when the target raises, and add anerrorsignal so failures can be surfaced:result: Signal = Signal(object) done: Signal = Signal() + error: Signal = Signal(object) ... @Slot() def run(self): - self.result.emit(self._target(*self._args, **self._kwargs)) - self.done.emit() + try: + self.result.emit(self._target(*self._args, **self._kwargs)) + except BaseException as exc: + import traceback + traceback.print_exc() + self.error.emit(exc) + finally: + self.done.emit()Verification
Used a small repro harness (not included in the PR) that drives each failure path without launching the GUI:
None, no backupsget_cargo_datareturnsNone, caller TypeErrorsRuntimeErrorwith a clear messagerequests.Session.getraisesConnectionErrorfetch_jsonreturnsNoneThreadtarget raisesdonenever emitted, splash hangsdoneemitted, traceback printedIn real terms: after this change, a transient wiki/Cloudflare failure during cargo load still fails — but it fails visibly (traceback in stderr,
donefires, app can move forward / show an error) instead of silently freezing the splash.Out of scope
Thread.errorsignal in the splash UI / showing a user-facing message box. Worth doing as a follow-up, but kept separate so this change stays focused on the freeze itself.