fix(desktop): update-check failures name the real cause instead of 'couldn't reach the update server'
A GitHub outage, a rate limit, a corporate proxy intercepting TLS and a DNS failure all rendered as the same generic line, so #105855 read as a Hermes bug during a run of GitHub incidents. The main process now classifies the failure (HTTP status incl. 403/429 rate-limit and 5xx outage wording, DNS, timeout, connection refused/reset, TLS) into one actionable sentence; the overlay shows it under the title and About appends it to the status line.
This commit is contained in:
@@ -3257,7 +3257,7 @@ async function checkUpdatesViaApi({ slug, branch, currentSha }) {
|
||||
try {
|
||||
targetSha = String(await fetchGitHubApi(branchTipApiUrl(slug, branch), 'application/vnd.github.sha')).trim()
|
||||
} catch (error) {
|
||||
return { error: 'fetch-failed', message: `GitHub API: ${error?.message || error}` }
|
||||
return { error: 'fetch-failed', message: describeUpdateCheckFailure(error) }
|
||||
}
|
||||
|
||||
if (!/^[0-9a-f]{40}$/i.test(targetSha)) {
|
||||
@@ -3315,6 +3315,45 @@ async function checkUpdatesViaLsRemote({ updateRoot, branch, currentSha }) {
|
||||
return { behind: null, updateAvailable: true, targetSha, commits: [] }
|
||||
}
|
||||
|
||||
// One line a user can act on (or paste into a bug report) instead of the
|
||||
// generic "couldn't reach the update server": which host, which failure.
|
||||
// #105855 was a run of GitHub outages that read as a Hermes bug because the
|
||||
// UI hid the cause.
|
||||
function describeUpdateCheckFailure(error) {
|
||||
const status = error?.statusCode
|
||||
const code = error?.code
|
||||
|
||||
if (status === 403 || status === 429) {
|
||||
return `GitHub API rate limit reached (HTTP ${status}) — try again in an hour.`
|
||||
}
|
||||
|
||||
if (typeof status === 'number' && status >= 500) {
|
||||
return `GitHub is having trouble (HTTP ${status} from api.github.com) — check githubstatus.com and try again later.`
|
||||
}
|
||||
|
||||
if (typeof status === 'number') {
|
||||
return `api.github.com answered HTTP ${status}.`
|
||||
}
|
||||
|
||||
if (code === 'ENOTFOUND' || code === 'EAI_AGAIN') {
|
||||
return 'DNS lookup for api.github.com failed — check your connection or proxy.'
|
||||
}
|
||||
|
||||
if (code === 'ETIMEDOUT' || error?.message === 'timeout') {
|
||||
return 'api.github.com did not answer within 10 seconds.'
|
||||
}
|
||||
|
||||
if (code === 'ECONNREFUSED' || code === 'ECONNRESET' || code === 'EHOSTUNREACH' || code === 'ENETUNREACH') {
|
||||
return `Connection to api.github.com failed (${code}) — a firewall or proxy may be blocking it.`
|
||||
}
|
||||
|
||||
if (typeof code === 'string' && /CERT|SSL|TLS/i.test(code)) {
|
||||
return `TLS handshake with api.github.com failed (${code}) — a proxy may be intercepting HTTPS.`
|
||||
}
|
||||
|
||||
return `api.github.com: ${error?.message || String(error)}`
|
||||
}
|
||||
|
||||
function fetchGitHubApi(url, accept = 'application/vnd.github+json') {
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = https.get(
|
||||
@@ -3335,7 +3374,7 @@ function fetchGitHubApi(url, accept = 'application/vnd.github+json') {
|
||||
const body = Buffer.concat(chunks).toString('utf8')
|
||||
|
||||
if ((res.statusCode || 500) >= 400) {
|
||||
reject(new Error(`HTTP ${res.statusCode}`))
|
||||
reject(Object.assign(new Error(`HTTP ${res.statusCode}`), { statusCode: res.statusCode }))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ export function AboutSettings() {
|
||||
statusLine = status?.message ?? a.cantUpdate
|
||||
statusTone = 'error'
|
||||
} else if (status?.error) {
|
||||
statusLine = a.cantReach
|
||||
statusLine = status.message ? `${a.cantReach} ${status.message}` : a.cantReach
|
||||
statusTone = 'error'
|
||||
} else if (applying) {
|
||||
statusLine = a.installing
|
||||
|
||||
@@ -215,6 +215,7 @@ function IdleView({
|
||||
</Button>
|
||||
}
|
||||
body={u.connectionRetry}
|
||||
detail={status.message}
|
||||
icon={<ErrorIcon />}
|
||||
title={u.checkFailedTitle}
|
||||
/>
|
||||
@@ -557,11 +558,15 @@ function ErrorView({ message, onDismiss, onRetry }: { message: string; onDismiss
|
||||
function CenteredStatus({
|
||||
action,
|
||||
body,
|
||||
detail,
|
||||
icon,
|
||||
title
|
||||
}: {
|
||||
action?: React.ReactNode
|
||||
body?: string
|
||||
/** Diagnostic line from the main process (HTTP status, DNS, TLS…), shown
|
||||
* verbatim so a bug report carries the real cause. */
|
||||
detail?: string
|
||||
icon: React.ReactNode
|
||||
title: string
|
||||
}) {
|
||||
@@ -572,6 +577,11 @@ function CenteredStatus({
|
||||
|
||||
<DialogTitle className="text-center text-lg">{title}</DialogTitle>
|
||||
{body && <DialogDescription className="text-center text-sm">{body}</DialogDescription>}
|
||||
{detail && (
|
||||
<p className="max-w-sm break-words rounded-md bg-muted/40 px-2 py-1 font-mono text-xs text-muted-foreground">
|
||||
{detail}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{action && <div className="flex justify-center">{action}</div>}
|
||||
|
||||
Reference in New Issue
Block a user