From f5ed7ae491a07f3ed57eed47046b3c974bb1fcab Mon Sep 17 00:00:00 2001 From: xadyz1 Date: Sun, 26 Jul 2026 19:53:23 +0100 Subject: [PATCH] fix: handle empty API responses in frontend and return JSON on server crash --- frontend/js/api.js | 10 ++++++++-- server/server.js | 9 +++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/frontend/js/api.js b/frontend/js/api.js index 7149d25..072a530 100644 --- a/frontend/js/api.js +++ b/frontend/js/api.js @@ -99,9 +99,15 @@ export const api = { } xhr.onload = () => { if (xhr.status >= 200 && xhr.status < 300) { - resolve(JSON.parse(xhr.responseText)); + try { + resolve(JSON.parse(xhr.responseText)); + } catch { + resolve({ ok: true }); // handle empty/non-JSON 2xx response + } } else { - reject(new Error('Upload failed')); + let msg = 'Upload failed'; + try { msg = JSON.parse(xhr.responseText).error || msg; } catch {} + reject(new Error(msg)); } }; xhr.onerror = () => reject(new Error('Upload failed')); diff --git a/server/server.js b/server/server.js index 7c499c9..1897026 100644 --- a/server/server.js +++ b/server/server.js @@ -965,6 +965,15 @@ app.get('/download/apk', (req, res) => { res.sendFile(apk.path, (err) => { if (err) release(); }); }); +// Global API error handler — prevents Express from sending HTML errors on API routes +app.use((err, req, res, next) => { + console.error('[Unhandled Express Error]', err); + if (req.path.startsWith('/api/')) { + return res.status(500).json({ error: 'Internal server error' }); + } + next(err); +}); + // SPA fallback for app routes. Unmatched /api/ paths return 404 so misrouted // clients fail fast instead of hanging until Cloudflare's 15s upstream timeout. app.get('*', (req, res) => {