Prevent updater check UI lockups with timeout safeguards (v4.1.10)

This commit is contained in:
xRangerDE 2026-02-21 00:30:24 +01:00
parent 3695c096ba
commit 9392398db7
5 changed files with 37 additions and 8 deletions

View File

@ -1,12 +1,12 @@
{ {
"name": "twitch-vod-manager", "name": "twitch-vod-manager",
"version": "4.1.9", "version": "4.1.10",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "twitch-vod-manager", "name": "twitch-vod-manager",
"version": "4.1.9", "version": "4.1.10",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"axios": "^1.6.0", "axios": "^1.6.0",

View File

@ -1,6 +1,6 @@
{ {
"name": "twitch-vod-manager", "name": "twitch-vod-manager",
"version": "4.1.9", "version": "4.1.10",
"description": "Twitch VOD Manager - Download Twitch VODs easily", "description": "Twitch VOD Manager - Download Twitch VODs easily",
"main": "dist/main.js", "main": "dist/main.js",
"author": "xRangerDE", "author": "xRangerDE",

View File

@ -457,7 +457,7 @@
<div class="settings-card"> <div class="settings-card">
<h3 id="updateTitle">Updates</h3> <h3 id="updateTitle">Updates</h3>
<p id="versionInfo" style="margin-bottom: 10px; color: var(--text-secondary);">Version: v4.1.9</p> <p id="versionInfo" style="margin-bottom: 10px; color: var(--text-secondary);">Version: v4.1.10</p>
<button class="btn-secondary" id="checkUpdateBtn" onclick="checkUpdate()">Nach Updates suchen</button> <button class="btn-secondary" id="checkUpdateBtn" onclick="checkUpdate()">Nach Updates suchen</button>
</div> </div>
@ -502,7 +502,7 @@
<div class="status-dot" id="statusDot"></div> <div class="status-dot" id="statusDot"></div>
<span id="statusText">Nicht verbunden</span> <span id="statusText">Nicht verbunden</span>
</div> </div>
<span id="versionText">v4.1.9</span> <span id="versionText">v4.1.10</span>
</div> </div>
</main> </main>
</div> </div>

View File

@ -8,7 +8,7 @@ import { autoUpdater } from 'electron-updater';
// ========================================== // ==========================================
// CONFIG & CONSTANTS // CONFIG & CONSTANTS
// ========================================== // ==========================================
const APP_VERSION = '4.1.9'; const APP_VERSION = '4.1.10';
const UPDATE_CHECK_URL = 'http://24-music.de/version.json'; const UPDATE_CHECK_URL = 'http://24-music.de/version.json';
// Paths // Paths
@ -34,6 +34,7 @@ const AUTO_UPDATE_CHECK_INTERVAL_MS = 10 * 60 * 1000;
const AUTO_UPDATE_STARTUP_CHECK_DELAY_MS = 5000; const AUTO_UPDATE_STARTUP_CHECK_DELAY_MS = 5000;
const AUTO_UPDATE_MIN_CHECK_GAP_MS = 45 * 1000; const AUTO_UPDATE_MIN_CHECK_GAP_MS = 45 * 1000;
const AUTO_UPDATE_AUTO_DOWNLOAD = true; const AUTO_UPDATE_AUTO_DOWNLOAD = true;
const AUTO_UPDATE_CHECK_TIMEOUT_MS = 30 * 1000;
const CACHE_CLEANUP_INTERVAL_MS = 60 * 1000; const CACHE_CLEANUP_INTERVAL_MS = 60 * 1000;
const MAX_LOGIN_TO_USER_ID_CACHE_ENTRIES = 4096; const MAX_LOGIN_TO_USER_ID_CACHE_ENTRIES = 4096;
const MAX_VOD_LIST_CACHE_ENTRIES = 512; const MAX_VOD_LIST_CACHE_ENTRIES = 512;
@ -2884,7 +2885,23 @@ async function requestUpdateCheck(source: UpdateCheckSource, force = false): Pro
appendDebugLog('update-check-start', { source }); appendDebugLog('update-check-start', { source });
try { try {
await autoUpdater.checkForUpdates(); let timeoutHandle: NodeJS.Timeout | null = null;
try {
await Promise.race([
autoUpdater.checkForUpdates(),
new Promise<never>((_, reject) => {
timeoutHandle = setTimeout(() => {
reject(new Error(`Update check timed out after ${AUTO_UPDATE_CHECK_TIMEOUT_MS}ms`));
}, AUTO_UPDATE_CHECK_TIMEOUT_MS);
})
]);
} finally {
if (timeoutHandle) {
clearTimeout(timeoutHandle);
timeoutHandle = null;
}
}
return { started: true }; return { started: true };
} catch (err) { } catch (err) {
appendDebugLog('update-check-failed', { source, error: String(err) }); appendDebugLog('update-check-failed', { source, error: String(err) });

View File

@ -88,6 +88,16 @@ async function checkUpdate(): Promise<void> {
notifyUpdate(UI_TEXT.updates.checkInProgress, 'info'); notifyUpdate(UI_TEXT.updates.checkInProgress, 'info');
return; return;
} }
manualUpdateCheckPending = false;
updateCheckInProgress = false;
setCheckButtonCheckingState(false);
window.setTimeout(() => {
if (!updateReady && byId('updateBanner').style.display !== 'flex') {
notifyUpdate(UI_TEXT.updates.latest, 'info');
}
}, 2500);
} catch { } catch {
manualUpdateCheckPending = false; manualUpdateCheckPending = false;
updateCheckInProgress = false; updateCheckInProgress = false;
@ -141,7 +151,9 @@ function downloadUpdate(): void {
window.api.onUpdateChecking(() => { window.api.onUpdateChecking(() => {
updateCheckInProgress = true; updateCheckInProgress = true;
setCheckButtonCheckingState(true); if (manualUpdateCheckPending) {
setCheckButtonCheckingState(true);
}
}); });
window.api.onUpdateAvailable((info: UpdateInfo) => { window.api.onUpdateAvailable((info: UpdateInfo) => {