From 96001959548d81dbb5f14fcbd0f185fe645c7c50 Mon Sep 17 00:00:00 2001 From: Administrator Date: Sat, 21 Mar 2026 11:52:13 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix:=20batch-done=20resilience,?= =?UTF-8?q?=20input=20validation,=20VOE=20JSON=20parse?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - batch-done handler: appendHistory failure no longer prevents the upload-batch-done event from reaching the renderer (UI would get stuck) - remote:input-event: validate x/y as finite numbers before passing to sendInputEvent (prevents NaN/Infinity crash) - VOE upload server: wrap JSON.parse in try-catch with clear error message instead of raw stack trace Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/voe-upload.js | 5 ++++- main.js | 10 +++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/voe-upload.js b/lib/voe-upload.js index a76c2ca..03bb75c 100644 --- a/lib/voe-upload.js +++ b/lib/voe-upload.js @@ -168,7 +168,10 @@ class VoeUploader { } }); const body = await res.text(); - const data = JSON.parse(body); + let data; + try { data = JSON.parse(body); } catch { + throw new Error(`VOE: Upload-Server Antwort war kein JSON: ${body.slice(0, 200)}`); + } if (!data || !data.success || !data.server) { throw new Error('VOE: Kein Upload-Server erhalten von delivery-node'); diff --git a/main.js b/main.js index 55fe9b3..c9dc735 100644 --- a/main.js +++ b/main.js @@ -716,7 +716,9 @@ ipcMain.handle('start-upload', (_event, payload) => { uploadManager.on('batch-done', async (summary) => { debugLog(`batch-done: total=${summary.total} ok=${summary.succeeded} fail=${summary.failed}`); - await configStore.appendHistory(summary); + try { await configStore.appendHistory(summary); } catch (err) { + debugLog(`appendHistory failed: ${err.message}`); + } if (mainWindow && !mainWindow.isDestroyed()) { mainWindow.webContents.send('upload-batch-done', summary); } @@ -1056,8 +1058,10 @@ ipcMain.on('remote:input-event', (_event, data) => { const capturedH = winBounds.height - dwm; // only bottom has invisible border const contentOffsetX = contentBounds.x - (winBounds.x + dwm); const contentOffsetY = contentBounds.y - winBounds.y; - const x = Math.round((data.x || 0) * capturedW - contentOffsetX); - const y = Math.round((data.y || 0) * capturedH - contentOffsetY); + const rawX = typeof data.x === 'number' && isFinite(data.x) ? data.x : 0; + const rawY = typeof data.y === 'number' && isFinite(data.y) ? data.y : 0; + const x = Math.round(rawX * capturedW - contentOffsetX); + const y = Math.round(rawY * capturedH - contentOffsetY); switch (data.type) { case 'mousemove':