diff --git a/src/app/(Home)/(Workflow)/domains/[domain]/[cluster]/workflows/[workflowId]/[runId]/error.tsx b/src/app/(Home)/(Workflow)/domains/[domain]/[cluster]/workflows/[workflowId]/[runId]/error.tsx deleted file mode 100644 index 9f158df51..000000000 --- a/src/app/(Home)/(Workflow)/domains/[domain]/[cluster]/workflows/[workflowId]/[runId]/error.tsx +++ /dev/null @@ -1,14 +0,0 @@ -'use client'; -import ErrorPanel from '@/components/error-panel/error-panel'; - -export default function WorkflowPageError({ - error, - reset, -}: Readonly<{ - error: Error; - reset: () => void; -}>) { - return ( - - ); -} diff --git a/src/app/(Home)/(Workflow)/domains/[domain]/[cluster]/workflows/[workflowId]/error.tsx b/src/app/(Home)/(Workflow)/domains/[domain]/[cluster]/workflows/[workflowId]/error.tsx new file mode 100644 index 000000000..1a273d9f9 --- /dev/null +++ b/src/app/(Home)/(Workflow)/domains/[domain]/[cluster]/workflows/[workflowId]/error.tsx @@ -0,0 +1,4 @@ +'use client'; +import WorkflowPageError from '@/views/workflow-page/workflow-page-error/workflow-page-error'; + +export default WorkflowPageError; diff --git a/src/route-handlers/describe-workflow/describe-workflow.ts b/src/route-handlers/describe-workflow/describe-workflow.ts index 84db4c675..0e8add71e 100644 --- a/src/route-handlers/describe-workflow/describe-workflow.ts +++ b/src/route-handlers/describe-workflow/describe-workflow.ts @@ -122,21 +122,39 @@ export default async function describeWorkflow( }; return NextResponse.json(res); } catch (e) { - logger.error( - { requestParams: decodedParams, cause: e }, - 'Error fetching workflow execution info' - ); + // skips logs for NotFound errors + // treat 400 responses for requesting unconfigured archives as 404 + if ( + e instanceof GRPCError && + (e.httpStatusCode === 404 || + (e.httpStatusCode === 400 && + e.message === + 'Requested workflow history not found, may have passed retention period.')) + ) { + return NextResponse.json( + { + message: 'Requested workflow history not found', + cause: e, + }, + { status: 404 } + ); + } else { + logger.error( + { requestParams: decodedParams, cause: e }, + 'Error fetching workflow execution info' + ); - return NextResponse.json( - { - message: - e instanceof GRPCError - ? e.message - : 'Error fetching workflow execution info', - cause: e, - }, - { status: getHTTPStatusCode(e) } - ); + return NextResponse.json( + { + message: + e instanceof GRPCError + ? e.message + : 'Error fetching workflow execution info', + cause: e, + }, + { status: getHTTPStatusCode(e) } + ); + } } } } diff --git a/src/views/workflow-page/workflow-page-error/__tests__/domain-page-error.test.tsx b/src/views/workflow-page/workflow-page-error/__tests__/domain-page-error.test.tsx new file mode 100644 index 000000000..c54e5ee5c --- /dev/null +++ b/src/views/workflow-page/workflow-page-error/__tests__/domain-page-error.test.tsx @@ -0,0 +1,49 @@ +import React from 'react'; + +import { render, screen } from '@/test-utils/rtl'; + +import { RequestError } from '@/utils/request/request-error'; + +import WorkflowPageError from '../workflow-page-error'; + +jest.mock('next/navigation', () => ({ + ...jest.requireActual('next/navigation'), + useParams: () => ({ + domain: 'test-domain', + cluster: 'test-cluster', + }), +})); + +jest.mock('@/components/error-panel/error-panel', () => + jest.fn(({ message }: { message: string }) =>
{message}
) +); + +describe(WorkflowPageError.name, () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders error page correctly', () => { + render( + {}} + /> + ); + expect(screen.getByText('Failed to load workflow')).toBeInTheDocument(); + }); + + it('renders "not found" error page correctly', () => { + render( + {}} + /> + ); + expect( + screen.getByText( + 'Workflow was not found, it may have passed retention period' + ) + ).toBeInTheDocument(); + }); +}); diff --git a/src/views/workflow-page/workflow-page-error/workflow-page-error.tsx b/src/views/workflow-page/workflow-page-error/workflow-page-error.tsx new file mode 100644 index 000000000..7ecd78f90 --- /dev/null +++ b/src/views/workflow-page/workflow-page-error/workflow-page-error.tsx @@ -0,0 +1,43 @@ +'use client'; +import { useParams } from 'next/navigation'; + +import ErrorPanel from '@/components/error-panel/error-panel'; +import { RequestError } from '@/utils/request/request-error'; + +import { type Props } from './workflow-page-error.types'; + +export default function WorkflowPageError({ error, reset }: Props) { + const { domain, cluster } = useParams(); + + if (error instanceof RequestError && error.status === 404) { + return ( + + ); + } + + return ( + + ); +} diff --git a/src/views/workflow-page/workflow-page-error/workflow-page-error.types.ts b/src/views/workflow-page/workflow-page-error/workflow-page-error.types.ts new file mode 100644 index 000000000..c58d444d6 --- /dev/null +++ b/src/views/workflow-page/workflow-page-error/workflow-page-error.types.ts @@ -0,0 +1,4 @@ +export type Props = { + error: Error; + reset: () => void; +};