diff --git a/src/app/configure-tasks-app/page.tsx b/src/app/configure-tasks-app/page.tsx index db28eac69..9a0bc17d7 100644 --- a/src/app/configure-tasks-app/page.tsx +++ b/src/app/configure-tasks-app/page.tsx @@ -17,7 +17,9 @@ import { AutoArchiveSection } from '@/app/configure-tasks-app/ui/AutoArchiveSect import { ClientViewSettingsSection } from '@/app/configure-tasks-app/ui/ClientViewSettingsSection' import { StatusCustomizationSection } from '@/app/configure-tasks-app/ui/StatusCustomizationSection' import { ClientViewSettings } from '@/types/dto/workspaceSettings.dto' +import { SilentError } from '@/components/templates/SilentError' import { Stack } from '@mui/material' +import { z } from 'zod' async function getAllWorkflowStates(token: string): Promise { const res = await fetch(`${apiUrl}/api/workflow-states?token=${token}`, { @@ -58,6 +60,23 @@ async function getWorkspaceSetting(token: string): Promise<{ autoArchiveAfterDay return await res.json() } +async function loadConfigureTasksAppPageData(token: string) { + try { + const [workflowStates, assignee, templates, tokenPayload, workspaceSetting] = await Promise.all([ + getAllWorkflowStates(token), + addTypeToAssignee(await getAssigneeList(token)), + getAllTemplates(token), + getTokenPayload(token), + getWorkspaceSetting(token), + ]) + + return { workflowStates, assignee, templates, tokenPayload, workspaceSetting } + } catch (error) { + console.warn('configure-tasks-app: failed to load configuration', error) + return null + } +} + interface ConfigureTasksAppPageProps { searchParams: Promise<{ token: string @@ -67,13 +86,16 @@ interface ConfigureTasksAppPageProps { export default async function ConfigureTasksAppPage(props: ConfigureTasksAppPageProps) { const searchParams = await props.searchParams const { token } = searchParams - const [workflowStates, assignee, templates, tokenPayload, workspaceSetting] = await Promise.all([ - getAllWorkflowStates(token), - addTypeToAssignee(await getAssigneeList(token)), - getAllTemplates(token), - getTokenPayload(token), - getWorkspaceSetting(token), - ]) + if (!z.string().safeParse(token).success) { + return + } + + const pageData = await loadConfigureTasksAppPageData(token) + if (!pageData) { + return + } + + const { workflowStates, assignee, templates, tokenPayload, workspaceSetting } = pageData return ( }) { @@ -21,13 +21,24 @@ export default async function NotificationCenter(props: { searchParams: Promise< return } - const notificationDetail = await getNotificationDetail(token) + let notificationDetail + try { + notificationDetail = await getNotificationDetail(token) + } catch (error) { + console.warn('notification-center: failed to load notification', error) + return + } + if (!notificationDetail) return - const params = NotificationInProductCtaParamsSchema.parse(notificationDetail.deliveryTargets?.inProduct?.ctaParams) + const params = NotificationInProductCtaParamsSchema.safeParse( + notificationDetail.deliveryTargets?.inProduct?.ctaParams, + ) + if (!params.success) { + return + } - redirectIfTaskCta({ ...params, ...searchParams }, UserType.INTERNAL_USER, true) + redirectIfTaskCta({ ...params.data, ...searchParams }, UserType.INTERNAL_USER, true) - // Silent Error is shown if redirect fails. Only possible reason for redirect to not work can be of the taskId not found return } diff --git a/src/utils/CopilotAPI.ts b/src/utils/CopilotAPI.ts index eed475e79..27f7c7494 100644 --- a/src/utils/CopilotAPI.ts +++ b/src/utils/CopilotAPI.ts @@ -361,15 +361,29 @@ export class CopilotAPI { async _getNotificationSettings(): Promise { console.info('CopilotAPI#_getNotificationSettings') const appId = z.string({ message: 'Missing AppID in environment' }).parse(APP_ID) - const installs = await this.copilot.listAppInstalls() + + let installs + try { + installs = await this.copilot.listAppInstalls() + } catch (error) { + console.warn('CopilotAPI#_getNotificationSettings | Failed to list app installs', error) + return { notifications: [] } + } + const install = installs.find((entry) => entry.appId === appId) if (!install?.id) { console.info('CopilotAPI#_getNotificationSettings | No matching app install in workspace; no settings') return { notifications: [] } } const workspaceId = await this._resolveWorkspaceId() - const response = await this._manualFetch(`installs/${install.id}/notification-settings`, undefined, workspaceId) - return NotificationSettingsResponseSchema.parse(response) + + try { + const response = await this._manualFetch(`installs/${install.id}/notification-settings`, undefined, workspaceId) + return NotificationSettingsResponseSchema.parse(response) + } catch (error) { + console.warn('CopilotAPI#_getNotificationSettings | Failed to fetch notification settings', error) + return { notifications: [] } + } } // A single IU's live per-category notification preferences. Never cached — the platform evaluates