{"record":{"id":"cb7e5023fc59261b","repo":"jlcodes99/cockpit-tools","slug":"app-silent-update-check-failed-retrying-retr","errorCode":null,"errorMessage":"[App] Silent update check failed, retrying (${retryIndex}/${totalRetries}) in ${delayMs}ms:","messagePattern":"\\[App\\] Silent update check failed, retrying \\((.+?)/(.+?)\\) in (.+?)ms:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"src/App.tsx","lineNumber":2346,"sourceCode":"        );\n\n        writeUpdateLog('info', '启动检查立即执行');\n\n        if (autoInstall && !isLinuxManagedUpdate) {\n          // Silent update: check and download in background, install on restart\n          console.log('[App] Auto-install enabled, attempting silent update...');\n          writeUpdateLog('info', '后台自动更新已开启，尝试静默检查并下载');\n          let preparedUpdateInfo: UpdateInfo | null = null;\n          try {\n            const silentCheckStartedAt = performance.now();\n            const update = await retryWithBackoff(\n              async () => runUpdaterCheck(),\n              {\n                delaysMs: UPDATE_CHECK_RETRY_DELAYS_MS,\n                shouldRetry: isRetryableUpdaterError,\n                onRetry: ({ retryIndex, totalRetries, delayMs, error }) => {\n                  const compactError = sanitizeUpdaterErrorMessage(error);\n                  console.warn(\n                    `[App] Silent update check failed, retrying (${retryIndex}/${totalRetries}) in ${delayMs}ms:`,\n                    error,\n                  );\n                  writeUpdateLog(\n                    'warn',\n                    `静默更新检查失败，准备重试(${retryIndex}/${totalRetries})，delay=${delayMs}ms，error=${compactError}`,\n                  );\n                },\n              },\n            );\n            console.log(\n              `[StartupPerf][UpdateCheck] silent runUpdaterCheck completed in ${(performance.now() - silentCheckStartedAt).toFixed(2)}ms; hasUpdate=${Boolean(update)}`,\n            );\n            if (update) {\n              if (skippedVersion && update.version === skippedVersion) {\n                console.log('[App] Update skipped by user, ignoring:', update.version);\n                writeUpdateLog('info', `检测到新版本但已跳过: version=${update.version}`);\n                await closeUpdaterHandle(update);","sourceCodeStart":2328,"sourceCodeEnd":2364,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/src/App.tsx#L2328-L2364","documentation":"The silent (automatic) update check runs runUpdaterCheck through a retry helper; onRetry receives the failed attempt and logs this warning before scheduling the next attempt after delayMs. It indicates a transient updater failure, not a final one — the check will keep retrying per UPDATE_CHECK_RETRY_DELAYS_MS until attempts are exhausted.","triggerScenarios":"runUpdaterCheck() rejects with an error for which isRetryableUpdaterError returns true (network timeouts, DNS failures, 5xx from the update server, proxy errors) during the background silent update check.","commonSituations":"Offline or flaky network at app start; corporate proxy/firewall blocking the update endpoint; update server returning 503; TLS interception certificates.","solutions":["Nothing to fix if a later retry succeeds — this is informational; check the subsequent update log entries for final outcome","Verify network/proxy access to the update manifest URL from the affected machine","Compare the sanitized error (compactError in writeUpdateLog) against known retryable categories to find the root cause","If retries exhaust, surface a manual 'check for updates' action and consider increasing retry delays"],"exampleFix":"// before\nshouldRetry: isRetryableUpdaterError,\n// after\nshouldRetry: isRetryableUpdaterError,\ndelaysMs: navigator.onLine === false ? [] : UPDATE_CHECK_RETRY_DELAYS_MS, // skip retries when offline","handlingStrategy":"retry","validationCode":"if (typeof navigator !== 'undefined' && navigator.onLine === false) {\n  // skip update check entirely; retries cannot succeed offline\n  return;\n}","typeGuard":"function isRetryableUpdaterError(e: unknown): boolean {\n  const msg = e instanceof Error ? e.message : String(e);\n  return /timeout|network|ECONN|5\\d\\d|temporarily/i.test(msg);\n}","tryCatchPattern":"try {\n  await retryWithDelay(() => runUpdaterCheck(), {\n    delaysMs: UPDATE_CHECK_RETRY_DELAYS_MS,\n    shouldRetry: isRetryableUpdaterError,\n    onRetry: ({ retryIndex, totalRetries, delayMs, error }) => {\n      console.warn(`[App] Silent update check failed, retrying (${retryIndex}/${totalRetries}) in ${delayMs}ms:`, error);\n    },\n  });\n} catch (finalError) {\n  writeUpdateLog('error', sanitizeUpdaterErrorMessage(finalError));\n}","preventionTips":["Skip update checks when offline (navigator.onLine)","Only retry errors classified as retryable; fail fast on 4xx","Write every retry and the final outcome to the update log","Use escalating backoff delays to avoid hammering a struggling endpoint"],"tags":["updater","network","retry"],"backgroundTag":"update-check-failed","analyzedSha":"1ed8b77992d62ca81fabf744deb0839ad361d5bf","analyzedAt":"2026-09-05T09:51:41.178Z","contentChangedAt":"2026-09-05T09:51:41.178Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}