fix: gracefully degrade when widget_secret table is missing or access denied

The releases widget was crashing because throwIfActionForbiddenAsync
or the widgetSecrets query would throw before DB migrations are run.
Wrap in try/catch so the widget works without tokens in that case.
This commit is contained in:
Thomas Camlong committed 2026-06-27 10:57:14 +02:00
1 parent 8c51a3769e
commit 30107e4e76
1 file changed
+20 -16
+20 -16
View File
@@ -48,26 +48,30 @@ export const releasesRouter = createTRPCRouter({
let allowedRepoIds: Set<string> | null = null;
if (input.itemId) {
const item = await ctx.db.query.items.findFirst({ where: eq(items.id, input.itemId) });
if (item && item.kind === "releases") {
await throwIfActionForbiddenAsync(ctx, eq(boards.id, item.boardId), "view");
try {
const item = await ctx.db.query.items.findFirst({ where: eq(items.id, input.itemId) });
if (item && item.kind === "releases") {
await throwIfActionForbiddenAsync(ctx, eq(boards.id, item.boardId), "view");
const options = SuperJSON.parse<Record<string, unknown>>(item.options);
const repos = options.repositories as Array<{ id?: string }> | undefined;
if (repos) {
allowedRepoIds = new Set(repos.map((r) => r.id).filter((id): id is string => Boolean(id)));
}
const options = SuperJSON.parse<Record<string, unknown>>(item.options);
const repos = options.repositories as Array<{ id?: string }> | undefined;
if (repos) {
allowedRepoIds = new Set(repos.map((r) => r.id).filter((id): id is string => Boolean(id)));
}
const secrets = await ctx.db.query.widgetSecrets.findMany({
where: eq(widgetSecrets.itemId, input.itemId),
});
for (const secret of secrets) {
try {
tokensByProvider.set(secret.kind, decryptSecret(secret.value));
} catch {
// Skip corrupt secrets
const secrets = await ctx.db.query.widgetSecrets.findMany({
where: eq(widgetSecrets.itemId, input.itemId),
});
for (const secret of secrets) {
try {
tokensByProvider.set(secret.kind, decryptSecret(secret.value));
} catch {
// Skip corrupt secrets
}
}
}
} catch {
// Access denied or table not yet migrated -- proceed without tokens
}
}