From ae891480be75d5c8825bf155be5f9d63d40f8d59 Mon Sep 17 00:00:00 2001 From: ajnart Date: Wed, 15 Jul 2026 10:38:49 +0200 Subject: [PATCH] fix(releases): log instead of silently swallowing token load failures The outer catch at releases.ts:79 silently swallowed all errors when loading widget secrets, including the case where the widget_secret table didn't exist (migration not applied). This caused tokens to silently become undefined, leading to unauthenticated API calls and rate limit errors. Now logs a warning with the itemId and error so the issue is diagnosable in server logs instead of failing silently. --- packages/api/src/router/widgets/releases.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/api/src/router/widgets/releases.ts b/packages/api/src/router/widgets/releases.ts index 84e903627..d234a75c1 100644 --- a/packages/api/src/router/widgets/releases.ts +++ b/packages/api/src/router/widgets/releases.ts @@ -3,6 +3,7 @@ import { escapeForRegEx } from "@tiptap/react"; import { z } from "zod/v4"; import { decryptSecret } from "@homarr/common/server"; +import { createLogger } from "@homarr/core/infrastructure/logs"; import { eq } from "@homarr/db"; import { boards, items, widgetSecrets } from "@homarr/db/schema"; import { releaseProviderKinds } from "@homarr/definitions"; @@ -11,6 +12,8 @@ import { releasesRequestHandler } from "@homarr/request-handler/releases"; import { createTRPCRouter, publicProcedure } from "../../trpc"; import { throwIfActionForbiddenAsync } from "../board/board-access"; +const logger = createLogger({ module: "releasesRouter" }); + const formatVersionFilterRegex = (versionFilter: z.infer | undefined) => { if (!versionFilter) return undefined; @@ -71,13 +74,13 @@ export const releasesRouter = createTRPCRouter({ for (const secret of secrets) { try { tokensByProvider.set(secret.kind, decryptSecret(secret.value)); - } catch { - // Skip corrupt secrets + } catch (error) { + logger.warn("Failed to decrypt widget secret", { itemId: input.itemId, kind: secret.kind, error }); } } } - } catch { - // Access denied or table not yet migrated -- proceed without tokens + } catch (error) { + logger.warn("Failed to load release widget tokens", { itemId: input.itemId, error }); } }