From 7264f4bb5d1ae08a8cca82623aaa6c418afcebfd Mon Sep 17 00:00:00 2001 From: arpandhakal Date: Wed, 13 May 2026 15:28:29 +0545 Subject: [PATCH] fix(OUT-3674): surface real cause of getCustomFieldAccess failures The API route now propagates SDK/DB errors via handleError instead of bubbling an opaque 500, and the page-level helper includes the status code and response body snippet in its thrown error. Improves Sentry diagnostics for PROFILE-MANAGER-35 so we can distinguish bad-token failures from other upstream causes. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/app/api/custom-field-access/route.ts | 30 ++++++++++++++---------- src/app/manage/page.tsx | 3 ++- src/app/page.tsx | 3 ++- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/app/api/custom-field-access/route.ts b/src/app/api/custom-field-access/route.ts index fd8da27..932c6be 100644 --- a/src/app/api/custom-field-access/route.ts +++ b/src/app/api/custom-field-access/route.ts @@ -1,7 +1,7 @@ import { NextRequest, NextResponse } from 'next/server'; import { CustomFieldAccessRequestSchema } from '@/types/customFieldAccess'; import { CustomFieldAccessService } from '@/app/api/custom-field-access/services/customFieldAccess.service'; -import { respondError } from '@/utils/common'; +import { handleError, respondError } from '@/utils/common'; import { CopilotAPI } from '@/utils/copilotApiUtils'; import { z } from 'zod'; @@ -17,21 +17,25 @@ export async function GET(request: NextRequest) { if (!portalId) { return respondError('Missing portalId', 422); } - const copilotClient = new CopilotAPI(z.string().parse(token)); - const customFields = (await copilotClient.getCustomFields()).data; + try { + const copilotClient = new CopilotAPI(z.string().parse(token)); + const customFields = (await copilotClient.getCustomFields()).data; - const customFieldAccessService = new CustomFieldAccessService(); - const customFieldAccesses = await customFieldAccessService.findAll(z.string().parse(portalId)); + const customFieldAccessService = new CustomFieldAccessService(); + const customFieldAccesses = await customFieldAccessService.findAll(z.string().parse(portalId)); - const customFieldsWithAccess = customFields?.map((customField) => { - const customFieldAccess = customFieldAccesses.find((access) => access.customFieldId === customField.id); - return { - ...customField, - permission: customFieldAccess ? customFieldAccess.permissions : [], - }; - }); + const customFieldsWithAccess = customFields?.map((customField) => { + const customFieldAccess = customFieldAccesses.find((access) => access.customFieldId === customField.id); + return { + ...customField, + permission: customFieldAccess ? customFieldAccess.permissions : [], + }; + }); - return NextResponse.json({ data: customFieldsWithAccess }); + return NextResponse.json({ data: customFieldsWithAccess }); + } catch (error) { + return handleError(error); + } } export async function PUT(request: NextRequest) { diff --git a/src/app/manage/page.tsx b/src/app/manage/page.tsx index 5c57f96..23a7c94 100644 --- a/src/app/manage/page.tsx +++ b/src/app/manage/page.tsx @@ -35,7 +35,8 @@ async function getCustomFieldAccess({ const res = await fetch(`${apiUrl}/api/custom-field-access?token=${token}&portalId=${portalId}`); if (!res.ok) { - throw new Error('Something went wrong in getCustomFieldAccess'); + const body = await res.text().catch(() => ''); + throw new Error(`getCustomFieldAccess failed: ${res.status} ${body.slice(0, 200)}`); } const { data } = await res.json(); diff --git a/src/app/page.tsx b/src/app/page.tsx index b335b1f..cd94d1b 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -26,7 +26,8 @@ async function getCustomFieldAccess({ }); if (!res.ok) { - throw new Error('Something went wrong in getCustomFieldAccess'); + const body = await res.text().catch(() => ''); + throw new Error(`getCustomFieldAccess failed: ${res.status} ${body.slice(0, 200)}`); } const { data } = await res.json();