Fix update checker 406 error and add menu feedback dialogs

The GitHub /releases/latest endpoint returns 406 when electron-updater
requests it with Accept: application/json. Setting allowPrerelease=true
bypasses this by parsing the version from the atom feed directly.

The "Check for Updates" menu item now shows native dialogs so users get
feedback without needing to open Settings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Neil
2026-03-20 20:47:21 -07:00
co-authored by Claude Opus 4.6
parent 50595fbced
commit 4db7643a6b
2 changed files with 60 additions and 2 deletions
+8 -2
View File
@@ -14,7 +14,13 @@ import { registerShellHandlers } from './ipc/shell'
import { registerSessionHandlers } from './ipc/session'
import { registerUIHandlers } from './ipc/ui'
import { warmSystemFontFamilies } from './system-fonts'
import { setupAutoUpdater, checkForUpdates, getUpdateStatus, quitAndInstall } from './updater'
import {
setupAutoUpdater,
checkForUpdates,
checkForUpdatesFromMenu,
getUpdateStatus,
quitAndInstall
} from './updater'
let mainWindow: BrowserWindow | null = null
let store: Store | null = null
@@ -113,7 +119,7 @@ app.whenReady().then(() => {
{ role: 'about' },
{
label: 'Check for Updates...',
click: () => checkForUpdates()
click: () => checkForUpdatesFromMenu()
},
{
label: 'Settings',
+52
View File
@@ -26,6 +26,54 @@ export function checkForUpdates(): void {
})
}
/** Menu-triggered check that shows native dialogs for feedback */
export function checkForUpdatesFromMenu(): void {
if (!app.isPackaged || is.dev) {
dialog.showMessageBox({ type: 'info', message: 'You\u2019re on the latest version.' })
return
}
sendStatus({ state: 'checking' })
const onAvailable = (): void => {
cleanup()
}
const onNotAvailable = (): void => {
cleanup()
dialog.showMessageBox({ type: 'info', message: 'You\u2019re on the latest version.' })
}
const onError = (err: Error): void => {
cleanup()
dialog.showMessageBox({
type: 'error',
title: 'Update Error',
message: 'Could not check for updates.',
detail: err?.message
})
}
function cleanup(): void {
autoUpdater.off('update-available', onAvailable)
autoUpdater.off('update-not-available', onNotAvailable)
autoUpdater.off('error', onError)
}
autoUpdater.once('update-available', onAvailable)
autoUpdater.once('update-not-available', onNotAvailable)
autoUpdater.once('error', onError)
autoUpdater.checkForUpdates().catch((err) => {
sendStatus({ state: 'error', message: String(err?.message ?? err) })
cleanup()
dialog.showMessageBox({
type: 'error',
title: 'Update Error',
message: 'Could not check for updates.',
detail: String(err?.message ?? err)
})
})
}
export function quitAndInstall(): void {
autoUpdater.quitAndInstall()
}
@@ -38,6 +86,10 @@ export function setupAutoUpdater(mainWindow: BrowserWindow): void {
autoUpdater.autoDownload = true
autoUpdater.autoInstallOnAppQuit = true
// Use allowPrerelease to bypass broken /releases/latest endpoint (returns 406)
// and instead parse the version directly from the atom feed which works reliably.
// This is safe since we don't publish prerelease versions.
autoUpdater.allowPrerelease = true
autoUpdater.on('checking-for-update', () => {
sendStatus({ state: 'checking' })