From 62e7fa8be1ec1bbba05c2520a17a4461b4eae3f1 Mon Sep 17 00:00:00 2001 From: Guido Schmit Date: Wed, 8 Apr 2026 21:40:01 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20Google-Token-Fehler=20wird=20sichtbar=20?= =?UTF-8?q?gemacht=20und=20dem=20User=20gemeldet=20Wenn=20der=20Access-Tok?= =?UTF-8?q?en=20eines=20Google-Accounts=20abl=C3=A4uft=20und=20der=20Refre?= =?UTF-8?q?sh=20fehlschl=C3=A4gt,=20wurde=20die=20leere=20Terminliste=20bi?= =?UTF-8?q?sher=20still=20zur=C3=BCckgegeben=20(kein=20Log,=20keine=20UI-M?= =?UTF-8?q?eldung).=20Jetzt=20wird=20der=20Fehler=20geloggt,=20an=20den=20?= =?UTF-8?q?Aufrufer=20weitergegeben=20und=20als=20Toast-Meldung=20im=20Fro?= =?UTF-8?q?ntend=20angezeigt=20("Token=20abgelaufen=20=E2=80=93=20bitte=20?= =?UTF-8?q?Konto=20trennen=20und=20neu=20verbinden").=20Das=20Events-Endpo?= =?UTF-8?q?int=20gibt=20nun=20{events,=20errors}=20statt=20ein=20reines=20?= =?UTF-8?q?Array=20zur=C3=BCck;=20das=20Frontend=20extrahiert=20die=20Even?= =?UTF-8?q?ts=20entsprechend.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/routers/caldav_router.py | 4 +++- backend/routers/google_router.py | 5 +++-- frontend/js/calendar.js | 12 +++++++++--- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/backend/routers/caldav_router.py b/backend/routers/caldav_router.py index a0d61aa..1aa38e4 100644 --- a/backend/routers/caldav_router.py +++ b/backend/routers/caldav_router.py @@ -347,13 +347,15 @@ def get_events( .filter(models.GoogleAccount.user_id == current_user.id) .all() ) + google_errors = [] for g_acc in google_accounts: try: all_events.extend(get_google_events(g_acc, start_dt, end_dt, db)) except Exception as exc: logger.error("Error fetching Google Calendar for %s: %s", g_acc.email, exc) + google_errors.append({"email": g_acc.email}) - return all_events + return {"events": all_events, "errors": google_errors} @router.post("/events") diff --git a/backend/routers/google_router.py b/backend/routers/google_router.py index d771d61..0a1c443 100644 --- a/backend/routers/google_router.py +++ b/backend/routers/google_router.py @@ -373,8 +373,9 @@ def get_google_events(account: models.GoogleAccount, start_dt: datetime, end_dt: """Fetch events from all enabled Google calendars for an account.""" try: token = _refresh_access_token(account, db) - except Exception: - return [] + except Exception as exc: + logger.error("Token refresh failed for Google account %s: %s", account.email, exc) + raise all_events = [] try: diff --git a/frontend/js/calendar.js b/frontend/js/calendar.js index bfa22a3..631d012 100644 --- a/frontend/js/calendar.js +++ b/frontend/js/calendar.js @@ -124,7 +124,7 @@ function prefetchIfNeeded(viewStart, viewEnd) { const from = new Date(eventCache.end); const to = new Date(eventCache.end.getTime() + PREFETCH_EXT); api.get(`/caldav/events?start=${from.toISOString()}&end=${to.toISOString()}`) - .then(evs => { _mergeEvents(evs); eventCache.end = to; }) + .then(r => { _mergeEvents(r.events || r); eventCache.end = to; }) .catch(() => {}) .finally(() => { eventCache._fwdPending = false; }); } @@ -134,7 +134,7 @@ function prefetchIfNeeded(viewStart, viewEnd) { const from = new Date(eventCache.start.getTime() - PREFETCH_EXT); const to = new Date(eventCache.start); api.get(`/caldav/events?start=${from.toISOString()}&end=${to.toISOString()}`) - .then(evs => { _mergeEvents(evs); eventCache.start = from; }) + .then(r => { _mergeEvents(r.events || r); eventCache.start = from; }) .catch(() => {}) .finally(() => { eventCache._bwdPending = false; }); } @@ -161,7 +161,13 @@ async function fetchAndRender(force = false) { showLoading(); try { - const events = await api.get(`/caldav/events?start=${fetchStart.toISOString()}&end=${fetchEnd.toISOString()}`); + const resp = await api.get(`/caldav/events?start=${fetchStart.toISOString()}&end=${fetchEnd.toISOString()}`); + const events = resp.events || resp; + if (resp.errors && resp.errors.length) { + for (const err of resp.errors) { + showToast(`Google (${err.email}): Token abgelaufen – bitte Konto trennen und neu verbinden`, true); + } + } eventCache.start = fetchStart; eventCache.end = fetchEnd; eventCache.events = events;