jlcodes99/cockpit-tools · info

[App] Background manual update check failed, retrying (${ret

Error message

[App] Background manual update check failed, retrying (${retryIndex}/${totalRetries}) in ${delayMs}ms:

What it means

Same retry machinery as the silent check, but for a user-triggered manual update check running in the background. Each retryable failure of runUpdaterCheck logs this warning and schedules the next attempt; the user-facing update log also records a localized warning with the sanitized error. Final failure only matters after all retries in UPDATE_CHECK_RETRY_DELAYS_MS are consumed.

Source

Thrown at src/App.tsx:2606

        } else {
          // Auto-check only opens the dialog after a real update is found.
          if (autoInstall && isLinuxManagedUpdate) {
            writeUpdateLog(
              'info',
              `Linux 包管理安装(${updateRuntimeInfo?.linux_install_kind || 'unknown'})跳过静默下载,改为左上角一键安装入口`,
            );
          }
          writeUpdateLog('info', '后台自动更新关闭,先执行无弹窗检查,仅在发现新版本时显示左上角入口');
          try {
            const manualCheckStartedAt = performance.now();
            const update = await retryWithBackoff(
              async () => runUpdaterCheck(),
              {
                delaysMs: UPDATE_CHECK_RETRY_DELAYS_MS,
                shouldRetry: isRetryableUpdaterError,
                onRetry: ({ retryIndex, totalRetries, delayMs, error }) => {
                  const compactError = sanitizeUpdaterErrorMessage(error);
                  console.warn(
                    `[App] Background manual update check failed, retrying (${retryIndex}/${totalRetries}) in ${delayMs}ms:`,
                    error,
                  );
                  writeUpdateLog(
                    'warn',
                    `后台手动更新检查失败,准备重试(${retryIndex}/${totalRetries}),delay=${delayMs}ms,error=${compactError}`,
                  );
                },
              },
            );
            console.log(
              `[StartupPerf][UpdateCheck] manual runUpdaterCheck completed in ${(performance.now() - manualCheckStartedAt).toFixed(2)}ms; hasUpdate=${Boolean(update)}`,
            );

            if (update) {
              if (skippedVersion && update.version === skippedVersion) {
                console.log('[App] Update skipped by user, ignoring:', update.version);
                writeUpdateLog('info', `检测到新版本但已跳过: version=${update.version}`);

View on GitHub (pinned to 1ed8b77992)

Solutions

  1. If a later retry succeeds, no action needed — verify via the update log's final entry
  2. Check connectivity/proxy to the update endpoint; test the manifest URL in a browser on the same machine
  3. Review compactError in the update log to classify the failure (timeout vs HTTP status vs TLS)
  4. If retries keep failing, show the user a clear error state with a retry button instead of only logging

Example fix

// before
onRetry: ({ retryIndex, totalRetries, delayMs, error }) => {
  console.warn(`[App] Background manual update check failed, retrying (${retryIndex}/${totalRetries})...`, error);
}
// after
onRetry: ({ retryIndex, totalRetries, delayMs, error }) => {
  console.warn(`[App] Background manual update check failed, retrying (${retryIndex}/${totalRetries})...`, sanitizeUpdaterErrorMessage(error));
  setUpdateCheckStatus('retrying', retryIndex, totalRetries); // keep UI informed
}
Defensive patterns

Strategy: retry

Validate before calling

if (typeof navigator !== 'undefined' && navigator.onLine === false) {
  setUpdateCheckStatus('offline');
  return;
}

Type guard

function isRetryableUpdaterError(e: unknown): boolean {
  const msg = e instanceof Error ? e.message : String(e);
  return /timeout|network|ECONN|5\d\d|temporarily/i.test(msg);
}

Try / catch

try {
  await retryWithDelay(() => runUpdaterCheck(), {
    delaysMs: UPDATE_CHECK_RETRY_DELAYS_MS,
    shouldRetry: isRetryableUpdaterError,
    onRetry: ({ retryIndex, totalRetries, delayMs, error }) => {
      console.warn(`[App] Background manual update check failed, retrying (${retryIndex}/${totalRetries}) in ${delayMs}ms:`, error);
      writeUpdateLog('warn', `后台手动更新检查失败,准备重试(${retryIndex}/${totalRetries}),error=${sanitizeUpdaterErrorMessage(error)}`);
    },
  });
} catch (finalError) {
  setUpdateCheckStatus('failed', sanitizeUpdaterErrorMessage(finalError));
}

Prevention

When it happens

Trigger: runUpdaterCheck() rejects with isRetryableUpdaterError === true (network timeout, DNS, HTTP 5xx, proxy errors) while a manual check triggered from the UI runs in the background.

Common situations: User clicks 'check for updates' while offline or behind a restrictive proxy; update CDN outage; VPN dropping mid-check.

Related errors


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