Skip to content

Reports stop resending refused events; desktop update restart and failure states - #1930

Merged
BarganConstantin merged 3 commits into
developmentfrom
fix/report-retry-and-update-states
Oct 4, 2026
Merged

BarganConstantin merged 3 commits into
developmentfrom
fix/report-retry-and-update-states

Conversation

@BarganConstantin

Copy link
Copy Markdown
Owner

What changes

  • Usage reports: a refused event is not sent again. An install, update, "active", "activated" or "rated" the API answers with a 4xx (other than 408 and 429) is now final for that event, instead of going out again on every heartbeat, about every ten minutes. No answer, a 5xx, a 408 or a 429 is still tried again on the heartbeat: the first retry is still the next beat, then the wait doubles each time, up to the six-hour check-in, and never sooner than a 429's or 503's Retry-After asks (capped at a day). A deletion stays owed until it lands, and is asked again on the same backoff rather than every beat. "Sent once" and "one active a day" in the README stay true.
  • Desktop: Restart to update on a .deb, .rpm or pacman install restarts the package way. It used to go by APPIMAGE alone, so a package install started from an environment that had it set took the AppImage restart. It now asks the same question the unattended-install rule does (the package-type file).
  • Desktop: the tray says when an update failed. The update row read "Check for updates" after any failure. It now reads "Update failed — try again", or, for an app that cannot replace itself where it is, "Move ccdeck to Applications to update" (macOS) / "Move the AppImage to a writable folder to update" (Linux). Clicking it checks again, as before. The window's update notice only ever shows a ready update, so it is unchanged.

Verification

  • npm run typecheck clean.
  • Full suite: 860 files, 11450 tests passed (3 workers, exit 0), before the rebase; the touched tests (15 files, 212 tests) rerun green after it.
  • New regression tests, each failing before its fix for the reason described:
    • reports-refused-event.test.ts: a 400/413/422 install was sent 7 times over six beats; an update, active, activated and rated likewise; a failed send was retried on all ~34 beats of six hours with no backoff; a 429 with Retry-After: 3600 was retried at the next beat. All go once now, failures back off, and Retry-After is waited for.
    • desktop-update-package-restart.test.ts: a deb/rpm/pacman install with APPIMAGE set never reached quitAndInstall; the AppImage path ran instead. The real AppImage still restarts the AppImage way.
    • desktop-update-failed-tray.test.ts: the row read "Check for updates" after a dropped download, an unwritable macOS bundle and an unwritable AppImage folder.
  • reports-checkin-retry.test.ts: its clock now runs with the fake timers, as a real one does, and the "keeps trying" case waits out the backoff instead of expecting a retry on every beat. desktop-tray-menu.test.ts: the error row's expected label changed from "Check for updates" to the new one.
  • No browser check: nothing here is drawn in the page. The tray row is checked by calling trayMenuItems with the updater's real state. Electron and the updater were never started, and no report was sent (fetch is stubbed).

Since the heartbeat checks in whatever is owed, an install, update,
active, activated or rated the API answered with a 4xx went out again
about every ten minutes, for good. A 4xx other than 408 and 429 is now
final for that event. No answer, a 5xx, a 408 or a 429 is still tried
again on the heartbeat, first on the next beat and then less often the
longer it fails, up to the six-hour check-in, and never sooner than a
Retry-After asks. A deletion stays owed until it lands.
Restart to update sent any Linux run with APPIMAGE in its environment
to the AppImage restart, so a .deb, .rpm or pacman install started from
a shell or launcher that had it set swapped and relaunched a file that
was not this app. It now asks the same question the unattended rule
does: whether this really is the AppImage, by the package-type file.
Every update failure went to the trace log alone, and the tray row read
"Check for updates" as if nothing had been looked for. The row now reads
"Update failed — try again", and for an app that cannot replace itself
where it is, what to do: "Move ccdeck to Applications to update" on
macOS, "Move the AppImage to a writable folder to update" on Linux. The
updater's error state carries which failure it was; clicked, the row
checks again as before.
@BarganConstantin
BarganConstantin merged commit 7980370 into development Oct 4, 2026
10 checks passed
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