diff --git a/src/app/admin/layout.tsx b/src/app/admin/layout.tsx index c275666..0d42720 100644 --- a/src/app/admin/layout.tsx +++ b/src/app/admin/layout.tsx @@ -64,13 +64,25 @@ export default async function AdminLayout({ children }: { children: React.ReactN redirect("/change-password"); } - // Resolve the active brand (URL > cookie > legacy > first of brand_ids) - const activeBrandId = await getActiveBrandId(adminUser); + // Resolve the active brand (URL > cookie > legacy > first of brand_ids). + // Wrapped in try/catch so a transient brand-resolution failure can't + // crash the whole admin shell — we fall back to null (no active brand). + let activeBrandId: string | null = null; + try { + activeBrandId = await getActiveBrandId(adminUser); + } catch (err) { + console.error("[admin/layout] getActiveBrandId failed:", err); + } - // Fetch accessible brands for the sidebar BrandSelector. We do this - // unconditionally — `listBrandsForAdmin` is cheap and the sidebar - // decides whether to show the dropdown. - const brands = await listBrandsForAdmin(); + // Fetch accessible brands for the sidebar BrandSelector. Wrapped in + // try/catch so the sidebar renders empty rather than crashing the page + // if the brands query fails. + let brands: Awaited> = []; + try { + brands = await listBrandsForAdmin(); + } catch (err) { + console.error("[admin/layout] listBrandsForAdmin failed:", err); + } return ( diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index 30f4fc3..a335a66 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -27,16 +27,21 @@ export default async function AdminPage() { // Resolve active brand via the canonical resolver (URL > cookie > legacy brand_id // > first of brand_ids). For platform_admin in dev mode this is null, so we // fall back to the first brand in the brands table to keep the dashboard's - // "Active Products" stat in sync with the billing page. + // "Active Products" stat in sync with the billing page. Wrapped in try/catch + // so a transient DB/network failure can't crash the whole admin page. let dashboardBrandId: string | null = adminUser ? await getActiveBrandId(adminUser) : null; if (!dashboardBrandId && adminUser?.role === "platform_admin") { - const { data: firstBrand } = await supabase - .from("brands") - .select("id") - .limit(1) - .single(); - if (firstBrand?.id) { - dashboardBrandId = firstBrand.id; + try { + const { data: firstBrand } = await supabase + .from("brands") + .select("id") + .limit(1) + .single(); + if (firstBrand?.id) { + dashboardBrandId = firstBrand.id; + } + } catch (err) { + console.error("[admin/page] supabase brands lookup failed:", err); } }