From 18e7f33ccd145292224cbeffde9fc30d143d97fb Mon Sep 17 00:00:00 2001 From: Ben Holmes Date: Mon, 13 May 2024 14:40:37 -0400 Subject: [PATCH] Actions: fix custom error message on client (#11030) * feat(test): error throwing on server * feat: correctly parse custom errors for the client * feat(test): custom errors on client * chore: changeset --- .changeset/slimy-comics-thank.md | 5 ++++ packages/astro/e2e/actions-blog.test.js | 16 ++++++++++++ .../actions-blog/src/actions/index.ts | 10 +++++++- .../src/components/PostComment.tsx | 10 +++++--- .../src/pages/blog/[...slug].astro | 5 +++- packages/astro/src/actions/runtime/route.ts | 23 +++++++++-------- .../src/actions/runtime/virtual/shared.ts | 25 ++++++++++--------- packages/astro/test/actions.test.js | 19 +++++++++++++- .../fixtures/actions/src/actions/index.ts | 18 +++++++++++-- .../actions/src/pages/user-or-throw.astro | 12 +++++++++ .../pages/{middleware.astro => user.astro} | 0 11 files changed, 112 insertions(+), 31 deletions(-) create mode 100644 .changeset/slimy-comics-thank.md create mode 100644 packages/astro/test/fixtures/actions/src/pages/user-or-throw.astro rename packages/astro/test/fixtures/actions/src/pages/{middleware.astro => user.astro} (100%) diff --git a/.changeset/slimy-comics-thank.md b/.changeset/slimy-comics-thank.md new file mode 100644 index 000000000000..25a71d762eb9 --- /dev/null +++ b/.changeset/slimy-comics-thank.md @@ -0,0 +1,5 @@ +--- +"astro": patch +--- + +Actions: Fix missing message for custom Action errors. diff --git a/packages/astro/e2e/actions-blog.test.js b/packages/astro/e2e/actions-blog.test.js index b98f74143ebd..1fc794279645 100644 --- a/packages/astro/e2e/actions-blog.test.js +++ b/packages/astro/e2e/actions-blog.test.js @@ -38,6 +38,22 @@ test.describe('Astro Actions - Blog', () => { await expect(page.locator('p[data-error="body"]')).toBeVisible(); }); + test('Comment action - custom error', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/blog/first-post/?commentPostIdOverride=bogus')); + + const authorInput = page.locator('input[name="author"]'); + const bodyInput = page.locator('textarea[name="body"]'); + await authorInput.fill('Ben'); + await bodyInput.fill('This should be long enough.'); + + const submitButton = page.getByLabel('Post comment'); + await submitButton.click(); + + const unexpectedError = page.locator('p[data-error="unexpected"]'); + await expect(unexpectedError).toBeVisible(); + await expect(unexpectedError).toContainText('NOT_FOUND: Post not found'); + }); + test('Comment action - success', async ({ page, astro }) => { await page.goto(astro.resolveUrl('/blog/first-post/')); diff --git a/packages/astro/e2e/fixtures/actions-blog/src/actions/index.ts b/packages/astro/e2e/fixtures/actions-blog/src/actions/index.ts index 4574caaaf50b..036cc087fdca 100644 --- a/packages/astro/e2e/fixtures/actions-blog/src/actions/index.ts +++ b/packages/astro/e2e/fixtures/actions-blog/src/actions/index.ts @@ -1,5 +1,6 @@ import { db, Comment, Likes, eq, sql } from 'astro:db'; -import { defineAction, z } from 'astro:actions'; +import { ActionError, defineAction, z } from 'astro:actions'; +import { getCollection } from 'astro:content'; export const server = { blog: { @@ -29,6 +30,13 @@ export const server = { body: z.string().min(10), }), handler: async ({ postId, author, body }) => { + if (!(await getCollection('blog')).find(b => b.id === postId)) { + throw new ActionError({ + code: 'NOT_FOUND', + message: 'Post not found', + }); + } + const comment = await db .insert(Comment) .values({ diff --git a/packages/astro/e2e/fixtures/actions-blog/src/components/PostComment.tsx b/packages/astro/e2e/fixtures/actions-blog/src/components/PostComment.tsx index 1b0d10a063fc..87d2154893da 100644 --- a/packages/astro/e2e/fixtures/actions-blog/src/components/PostComment.tsx +++ b/packages/astro/e2e/fixtures/actions-blog/src/components/PostComment.tsx @@ -10,6 +10,7 @@ export function PostComment({ }) { const [comments, setComments] = useState<{ author: string; body: string }[]>([]); const [bodyError, setBodyError] = useState(serverBodyError); + const [unexpectedError, setUnexpectedError] = useState(undefined); return ( <> @@ -22,14 +23,15 @@ export function PostComment({ const { data, error } = await actions.blog.comment.safe(formData); if (isInputError(error)) { return setBodyError(error.fields.body?.join(' ')); + } else if (error) { + return setUnexpectedError(`${error.code}: ${error.message}`); } - if (data) { - setBodyError(undefined); - setComments((c) => [data, ...c]); - } + setBodyError(undefined); + setComments((c) => [data, ...c]); form.reset(); }} > + {unexpectedError &&

{unexpectedError}

}