From b7e7f79a40aa6df083990ea9211407ad35e995ad Mon Sep 17 00:00:00 2001 From: Aslam H Date: Tue, 10 Sep 2024 20:03:25 +0700 Subject: [PATCH] fix: sentry, img validation --- web/app/actions.ts | 23 +++--- web/app/api/sentry-example-api/route.ts | 9 +++ web/app/sentry-example-page/page.tsx | 79 +++++++++++++++++++ .../components/image/image-edit-block.tsx | 8 +- web/next.config.mjs | 4 +- web/package.json | 2 +- 6 files changed, 108 insertions(+), 17 deletions(-) create mode 100644 web/app/api/sentry-example-api/route.ts create mode 100644 web/app/sentry-example-page/page.tsx diff --git a/web/app/actions.ts b/web/app/actions.ts index b3d3d04d..7431453f 100644 --- a/web/app/actions.ts +++ b/web/app/actions.ts @@ -32,18 +32,17 @@ export const sendFeedback = authedProcedure export const storeImage = authedProcedure .input( z.object({ - file: z.custom(file => { - if (!(file instanceof File)) { - throw new Error("Not a file") - } - if (!ALLOWED_FILE_TYPES.includes(file.type)) { - throw new Error("Invalid file type. Only JPEG, PNG, GIF, and WebP images are allowed.") - } - if (file.size > MAX_FILE_SIZE) { - throw new Error("File size exceeds the maximum limit of 1 MB.") - } - return true - }) + file: z + .any() + .refine(file => file instanceof File, { + message: "Not a file" + }) + .refine(file => ALLOWED_FILE_TYPES.includes(file.type), { + message: "Invalid file type. Only JPEG, PNG, GIF, and WebP images are allowed." + }) + .refine(file => file.size <= MAX_FILE_SIZE, { + message: "File size exceeds the maximum limit of 1 MB." + }) }), { type: "formData" } ) diff --git a/web/app/api/sentry-example-api/route.ts b/web/app/api/sentry-example-api/route.ts new file mode 100644 index 00000000..f486f3d1 --- /dev/null +++ b/web/app/api/sentry-example-api/route.ts @@ -0,0 +1,9 @@ +import { NextResponse } from "next/server"; + +export const dynamic = "force-dynamic"; + +// A faulty API route to test Sentry's error monitoring +export function GET() { + throw new Error("Sentry Example API Route Error"); + return NextResponse.json({ data: "Testing Sentry Error..." }); +} diff --git a/web/app/sentry-example-page/page.tsx b/web/app/sentry-example-page/page.tsx new file mode 100644 index 00000000..dd38d045 --- /dev/null +++ b/web/app/sentry-example-page/page.tsx @@ -0,0 +1,79 @@ +"use client"; + +import Head from "next/head"; +import * as Sentry from "@sentry/nextjs"; + +export default function Page() { + return ( +
+ + Sentry Onboarding + + + +
+

+ + + +

+ +

Get started by sending us a sample error:

+ + +

+ Next, look for the error on the{" "} + Issues Page. +

+

+ For more information, see{" "} + + https://docs.sentry.io/platforms/javascript/guides/nextjs/ + +

+
+
+ ); +} diff --git a/web/components/minimal-tiptap/components/image/image-edit-block.tsx b/web/components/minimal-tiptap/components/image/image-edit-block.tsx index f8786b8b..da4dd8be 100644 --- a/web/components/minimal-tiptap/components/image/image-edit-block.tsx +++ b/web/components/minimal-tiptap/components/image/image-edit-block.tsx @@ -41,6 +41,11 @@ const ImageEditBlock = ({ editor, className, close, ...props }: ImageEditBlockPr try { const [response, err] = await storeImage(formData) + + if (err) { + throw new Error(err.fieldErrors?.file?.join(", ")) + } + if (response?.fileModel) { editor.chain().setImage({ src: response.fileModel.content.src }).focus().run() close() @@ -48,7 +53,6 @@ const ImageEditBlock = ({ editor, className, close, ...props }: ImageEditBlockPr throw new Error("Failed to upload image") } } catch (error) { - console.error("Error uploading file:", error) setError(error instanceof Error ? error.message : "An unknown error occurred") } finally { setIsUploading(false) @@ -62,7 +66,7 @@ const ImageEditBlock = ({ editor, className, close, ...props }: ImageEditBlockPr return (
-
+
diff --git a/web/next.config.mjs b/web/next.config.mjs index 8be71289..ba15307d 100644 --- a/web/next.config.mjs +++ b/web/next.config.mjs @@ -64,11 +64,11 @@ export default withSentryConfig(nextConfig, { enabled: true }, - // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers. + // Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers. // This can increase your server load as well as your hosting bill. // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client- // side errors will fail. - tunnelRoute: "/monitoring", + // tunnelRoute: "/monitoring", // Hides source maps from generated client bundles hideSourceMaps: true, diff --git a/web/package.json b/web/package.json index ff84a657..c431e0cc 100644 --- a/web/package.json +++ b/web/package.json @@ -35,6 +35,7 @@ "@radix-ui/react-toggle": "^1.1.0", "@radix-ui/react-toggle-group": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.2", + "@sentry/nextjs": "^8.29.0", "@tanstack/react-virtual": "^3.10.7", "@tiptap/core": "^2.6.6", "@tiptap/extension-blockquote": "^2.6.6", @@ -95,7 +96,6 @@ "slugify": "^1.6.6", "sonner": "^1.5.0", "streaming-markdown": "^0.0.14", - "@sentry/nextjs": "^8.29.0", "tailwind-merge": "^2.5.2", "tailwindcss-animate": "^1.0.7", "vaul": "^0.9.2",