jlcodes99/cockpit-tools · error · Error

UPDATE_CANCELED_BY_USER

UPDATE_CANCELED_BY_USER

Error message

UPDATE_CANCELED_BY_USER

What it means

Cancellation sentinel in MainApp's unified update downloader: inside the retryWithBackoff attempt callback, updateCancelRequestedRef is set or the download task id no longer matches (superseded by a newer task), so UPDATE_CANCELED_BY_USER is thrown to unwind the retry loop immediately. It distinguishes a deliberate cancel/staleness abort from a real download failure.

Source

Thrown at src/App.tsx:1784

    updateDownloadOwnerRef.current = 'shared';
    setUpdateRetryStatus('');
    setUpdateDownloadError('');
    setUpdateErrorDetails('');
    setUpdateAction({
      state: 'downloading',
      version: expectedVersion,
      progress: 0,
      requiresInstall: true,
    });
    writeUpdateLog('info', `统一更新任务开始下载: version=${expectedVersion}`);

    let usedAttempts = 0;
    try {
      const downloadedUpdate = await retryWithBackoff(
        async (attempt) => {
          usedAttempts = attempt;
          if (updateCancelRequestedRef.current || updateDownloadTaskIdRef.current !== taskId) {
            throw createUpdaterCanceledError();
          }

          let candidate: UpdaterUpdate | null = null;
          try {
            candidate = await runUpdaterCheck();
            if (!candidate) {
              throw new Error('No update available from updater plugin');
            }
            activeUpdateDownloadRef.current = candidate;

            const candidateVersion = candidate.version;
            const { releaseNotes, releaseNotesZh } = parseUpdaterReleaseNotes(candidate.body);
            await invoke('save_pending_update_notes', {
              version: candidateVersion,
              releaseNotes,
              releaseNotesZh,
            }).catch((error) => {
              console.error('[App] Failed to cache shared update notes:', error);

View on GitHub (pinned to 1ed8b77992)

Solutions

  1. No action needed when the user cancelled — the UI state was already reset before the throw
  2. If it appears without user action, check whether another update task superseded this one (task-id mismatch)
  3. Ensure catch handlers treat this sentinel as control flow, not as an error to log/redact
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at src/App.tsx:1784 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05). Data as JSON: /api/errors/e1bf0e7308f8abf4. Report an issue: GitHub.