From a19066732075d275fa8c487e8243314a3f3bfce5 Mon Sep 17 00:00:00 2001 From: Daniel Volz Date: Sun, 18 Jan 2026 08:55:48 +0100 Subject: [PATCH] fix: improve import error handling and add refill_history table migration (#42) - Add CREATE TABLE IF NOT EXISTS for refill_history in ALTER migrations - Improve frontend import error handling to show server errors properly - Parse response as text first to handle non-JSON error responses --- backend/src/db/client.ts | 24 ++++++++++++++++++++++++ frontend/src/App.tsx | 23 ++++++++++++++++------- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/backend/src/db/client.ts b/backend/src/db/client.ts index c030acd..42a54bd 100644 --- a/backend/src/db/client.ts +++ b/backend/src/db/client.ts @@ -88,6 +88,30 @@ export async function runAlterMigrations(client: Client): Promise<{ success: boo } } + // Create tables that might be missing (silently fail if already exists) + const createTableMigrations = [ + // Added in v1.3.x - refill history tracking + `CREATE TABLE IF NOT EXISTS refill_history ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + medication_id INTEGER NOT NULL REFERENCES medications(id) ON DELETE CASCADE, + user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, + packs_added INTEGER NOT NULL DEFAULT 0, + loose_pills_added INTEGER NOT NULL DEFAULT 0, + refill_date INTEGER NOT NULL DEFAULT (strftime('%s','now')) + )`, + ]; + + for (const sql of createTableMigrations) { + try { + await client.execute(sql); + } catch (e: any) { + // Silently ignore "table already exists" errors + if (!e.message?.includes("already exists")) { + errors.push(e.message); + } + } + } + return { success: errors.length === 0, errors }; } diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 2a21692..e7908a0 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1151,17 +1151,26 @@ function AppContent() { body: JSON.stringify(pendingImportData), }); - if (!res.ok) { - const err = await res.json(); - alert(t('exportImport.importError') + ": " + (err.error || "Unknown error")); + // Get the response text first to handle non-JSON responses + const text = await res.text(); + let data; + try { + data = text ? JSON.parse(text) : {}; + } catch { + console.error("Import response parse error:", text); + alert(t('exportImport.importError') + ": Server returned invalid response"); + return; + } + + if (!res.ok) { + alert(t('exportImport.importError') + ": " + (data.error || `HTTP ${res.status}`)); return; } - const result = await res.json(); alert(t('exportImport.importSuccess') + "\n" + t('exportImport.importSuccessDetails', { - medications: result.imported.medications, - doses: result.imported.doseHistory, - shares: result.imported.shareLinks, + medications: data.imported?.medications || 0, + doses: data.imported?.doseHistory || 0, + shares: data.imported?.shareLinks || 0, })); // Reload all data