fix: attribute account-level token failures to each calendar
When a Home Assistant or Google token refresh fails, the whole account fetch aborts. Previously this raised, so the outer handler in caldav_router emitted a single sync error WITH NO calendar_id. Clients that preserve cached events per calendar (iOS) couldn't attribute it and wiped the affected calendars. Now both get_ha_events and get_google_events catch the token failure and emit one error per enabled calendar, each carrying its calendar_id — so every client can pin the failure to a specific calendar and keep its cached data. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -389,14 +389,28 @@ def get_google_events(account: models.GoogleAccount, start_dt: datetime, end_dt:
|
|||||||
{"source": "google", "name": ..., "message": ...} dicts for any
|
{"source": "google", "name": ..., "message": ...} dicts for any
|
||||||
calendar that failed to sync. Never includes raw exception text.
|
calendar that failed to sync. Never includes raw exception text.
|
||||||
"""
|
"""
|
||||||
|
all_events = []
|
||||||
|
errors = []
|
||||||
try:
|
try:
|
||||||
token = _refresh_access_token(account, db)
|
token = _refresh_access_token(account, db)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
|
# A token failure aborts the whole account, but attribute it to each
|
||||||
|
# enabled calendar so clients can pin the error to a specific calendar
|
||||||
|
# (and preserve that calendar's cached events instead of wiping it).
|
||||||
logger.error("Token refresh failed for Google account %s: %s", account.email, exc)
|
logger.error("Token refresh failed for Google account %s: %s", account.email, exc)
|
||||||
raise
|
for gcal in account.calendars:
|
||||||
|
if not gcal.enabled or gcal.sidebar_hidden:
|
||||||
|
continue
|
||||||
|
if _is_system_calendar(gcal.cal_id):
|
||||||
|
continue
|
||||||
|
errors.append({
|
||||||
|
"source": "google",
|
||||||
|
"name": f"{account.email} – {gcal.name}",
|
||||||
|
"calendar_id": gcal.id,
|
||||||
|
"message": "Sync fehlgeschlagen",
|
||||||
|
})
|
||||||
|
return all_events, errors
|
||||||
|
|
||||||
all_events = []
|
|
||||||
errors = []
|
|
||||||
for gcal in account.calendars:
|
for gcal in account.calendars:
|
||||||
if not gcal.enabled or gcal.sidebar_hidden:
|
if not gcal.enabled or gcal.sidebar_hidden:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -325,8 +325,20 @@ def get_ha_events(account: models.HomeAssistantAccount, start_dt: datetime, end_
|
|||||||
try:
|
try:
|
||||||
token = _get_valid_token(account, db)
|
token = _get_valid_token(account, db)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
|
# A token failure aborts the whole account, but attribute it to each
|
||||||
|
# enabled calendar so clients can pin the error to a specific calendar
|
||||||
|
# (and preserve that calendar's cached events instead of wiping it).
|
||||||
logger.error("HA token error for %s: %s", account.name, exc)
|
logger.error("HA token error for %s: %s", account.name, exc)
|
||||||
raise
|
for cal in account.calendars:
|
||||||
|
if not cal.enabled or cal.sidebar_hidden:
|
||||||
|
continue
|
||||||
|
errors.append({
|
||||||
|
"source": "homeassistant",
|
||||||
|
"name": f"{account.name} – {cal.name}",
|
||||||
|
"calendar_id": cal.id,
|
||||||
|
"message": "Sync fehlgeschlagen",
|
||||||
|
})
|
||||||
|
return all_events, errors
|
||||||
for cal in account.calendars:
|
for cal in account.calendars:
|
||||||
if not cal.enabled or cal.sidebar_hidden:
|
if not cal.enabled or cal.sidebar_hidden:
|
||||||
continue
|
continue
|
||||||
|
|||||||
Reference in New Issue
Block a user