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;
+};