From 891a2fe576a9c0895b5c876837166069bc288a71 Mon Sep 17 00:00:00 2001 From: ArslanSaleem Date: Mon, 28 Oct 2024 17:34:15 +0100 Subject: [PATCH] feat(rollbar): add error boundaries on app and main view --- frontend/.env.example | 3 +- frontend/package.json | 2 + frontend/src/app/(app)/layout.tsx | 10 ++- frontend/src/app/layout.tsx | 29 +++++--- frontend/src/components/ErrorFallback.tsx | 81 +++++++++++++++++++++ frontend/yarn.lock | 85 ++++++++++++++++++++++- 6 files changed, 196 insertions(+), 14 deletions(-) create mode 100644 frontend/src/components/ErrorFallback.tsx diff --git a/frontend/.env.example b/frontend/.env.example index 49593d3..3b74913 100644 --- a/frontend/.env.example +++ b/frontend/.env.example @@ -1,3 +1,4 @@ NEXT_PUBLIC_API_URL=http://localhost:3000/api/v1 NEXT_PUBLIC_STORAGE_URL=http://localhost:3000/api/assets -NEXT_PUBLIC_MIXPANEL_TOKEN=f2e8a71ab2bde33ebf346c5abf6ba9fa \ No newline at end of file +NEXT_PUBLIC_MIXPANEL_TOKEN=f2e8a71ab2bde33ebf346c5abf6ba9fa +NEXT_PUBLIC_ROLLBAR_ACCESS_TOKEN=0df0bee895044430880278e2b2a5b2d2 diff --git a/frontend/package.json b/frontend/package.json index 4faf62c..2c7c9f1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,6 +16,7 @@ "@radix-ui/react-context-menu": "^2.2.1", "@radix-ui/react-radio-group": "^1.2.0", "@react-pdf/renderer": "^4.0.0", + "@rollbar/react": "^0.12.0-beta", "@tanstack/react-query": "^5.51.1", "@tippyjs/react": "^4.2.6", "@types/mixpanel-browser": "^2.50.1", @@ -39,6 +40,7 @@ "react-quill": "^2.0.0", "rehype-sanitize": "^6.0.0", "remark-gfm": "^4.0.0", + "rollbar": "^2.26.4", "tailwind-merge": "^2.4.0" }, "devDependencies": { diff --git a/frontend/src/app/(app)/layout.tsx b/frontend/src/app/(app)/layout.tsx index f184192..06f391f 100644 --- a/frontend/src/app/(app)/layout.tsx +++ b/frontend/src/app/(app)/layout.tsx @@ -4,6 +4,8 @@ import { ScrollProvider } from "@/context/ScrollContext"; import Sidebar from "@/components/ui/Sidebar"; import Navbar from "@/components/ui/Navbar"; import "@/app/style/globals.css"; +import { ErrorBoundary } from "@rollbar/react"; +import { ViewErrorFallback } from "@/components/ErrorFallback"; export default function RootLayout({ children, @@ -17,9 +19,11 @@ export default function RootLayout({
-
- {children} -
+ +
+ {children} +
+
diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index ac7ff76..f38de68 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -4,9 +4,16 @@ import React from "react"; import { ReactQueryClientProvider } from "@/components/ReactQueryClientProvider"; import { Toaster } from "react-hot-toast"; import "@/app/style/globals.css"; +import { Provider, ErrorBoundary } from "@rollbar/react"; +import { GlobalErrorFallback } from "@/components/ErrorFallback"; const inter = Inter({ subsets: ["latin"] }); +const rollbarConfig = { + accessToken: process.env.NEXT_PUBLIC_ROLLBAR_ACCESS_TOKEN, + environment: process.env.NODE_ENV ?? "production", +}; + export const metadata: Metadata = { title: "PandaETL", description: @@ -22,14 +29,18 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - - - - - - {children} - - - + + + + + + + + {children} + + + + + ); } diff --git a/frontend/src/components/ErrorFallback.tsx b/frontend/src/components/ErrorFallback.tsx new file mode 100644 index 0000000..bb3f048 --- /dev/null +++ b/frontend/src/components/ErrorFallback.tsx @@ -0,0 +1,81 @@ +"use client"; +import React, { useEffect } from "react"; +import { Button } from "./ui/Button"; +import { useRouter } from "next/navigation"; + +// Define the props that the ErrorFallback will receive +interface ErrorFallbackProps { + error: Error | null; // The error that caused the fallback + resetError: () => void; // Function to reset the error state +} + +// Fallback UI component displayed on error +export const GlobalErrorFallback = ({ + error, + resetError, +}: ErrorFallbackProps) => { + const router = useRouter(); + + // useEffect(() => { + // const handleRouteChange = () => { + // resetError(); // Reset error state on route change + // }; + + // // Handle route change by overriding the router push method + // const originalPush = router.push; + // router.push = (...args) => { + // handleRouteChange(); // Call the reset function + // return originalPush(...args); + // }; + + // // Cleanup function to restore original router push method + // return () => { + // router.push = originalPush; + // }; + // }, [resetError, router]); + + return ( +
+

Oops! Something went wrong.

+

{error?.message || "We're working on fixing this issue."}

+ +
+ ); +}; + +export const ViewErrorFallback = ({ + error, + resetError, +}: ErrorFallbackProps) => { + const router = useRouter(); + + useEffect(() => { + const handleRouteChange = () => { + resetError(); // Reset error state on route change + }; + + // Handle route change by overriding the router push method + const originalPush = router.push; + router.push = (...args) => { + handleRouteChange(); // Call the reset function + return originalPush(...args); + }; + + // Cleanup function to restore original router push method + return () => { + router.push = originalPush; + }; + }, [resetError, router]); + + return ( +
+

Oops! Something went wrong.

+

{error?.message || "We're working on fixing this issue."}

+ +
+ ); +}; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index d938d4b..b329308 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -685,6 +685,13 @@ resolved "https://registry.npmjs.org/@react-types/shared/-/shared-3.24.1.tgz" integrity sha512-AUQeGYEm/zDTN6zLzdXolDxz3Jk5dDL7f506F07U8tBwxNNI3WRdhU84G0/AaFikOZzDXhOZDr3MhQMzyE7Ydw== +"@rollbar/react@^0.12.0-beta": + version "0.12.0-beta" + resolved "https://registry.yarnpkg.com/@rollbar/react/-/react-0.12.0-beta.tgz#b80dfab1535ece358a0e98a4f26aadee8b54edda" + integrity sha512-8udBX0lJwdBBq+O/jqDXpg/giHt8bo/Us1IlTkHEdCBO18Cjj7sxWJ80OPFxiPRNwZgZnhf2HbxQxvLN+4FeJA== + dependencies: + tiny-invariant "^1.1.0" + "@rrweb/types@^2.0.0-alpha.13": version "2.0.0-alpha.17" resolved "https://registry.yarnpkg.com/@rrweb/types/-/types-2.0.0-alpha.17.tgz#bf4af026e767022674892919692d59e766e9368e" @@ -1169,6 +1176,11 @@ ast-types-flow@^0.0.8: resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz" integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== +async@~3.2.3: + version "3.2.6" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" + integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" @@ -1460,6 +1472,11 @@ console-control-strings@^1.0.0, console-control-strings@^1.1.0: resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== +console-polyfill@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/console-polyfill/-/console-polyfill-0.3.0.tgz#84900902a18c47a5eba932be75fa44d23e8af861" + integrity sha512-w+JSDZS7XML43Xnwo2x5O5vxB0ID7T5BdqDtyqT6uiCAX2kZAgcWxNaGqT97tZfSHzfOcvrfsDAodKcJ3UvnXQ== + cross-fetch@^3.1.5: version "3.1.8" resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz" @@ -1542,6 +1559,13 @@ debug@^3.2.7: dependencies: ms "^2.1.1" +decache@^3.0.5: + version "3.1.0" + resolved "https://registry.yarnpkg.com/decache/-/decache-3.1.0.tgz#4f5036fbd6581fcc97237ac3954a244b9536c2da" + integrity sha512-p7D6wJ5EJFFq1CcF2lu1XeqKFLBob8jRQGNAvFLTsV3CbSKBl3VtliAVlUIGz2i9H6kEFnI2Amaft5ZopIG2Fw== + dependencies: + find "^0.2.4" + decode-named-character-reference@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz" @@ -1716,6 +1740,13 @@ environment@^1.0.0: resolved "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz" integrity sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q== +error-stack-parser@^2.0.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" + integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== + dependencies: + stackframe "^1.3.4" + es-abstract@^1.17.5, es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.1, es-abstract@^1.23.2, es-abstract@^1.23.3: version "1.23.3" resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz" @@ -2177,6 +2208,13 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" +find@^0.2.4: + version "0.2.9" + resolved "https://registry.yarnpkg.com/find/-/find-0.2.9.tgz#4b73f1ff9e56ad91b76e716407fe5ffe6554bb8c" + integrity sha512-7a4/LCiInB9xYMnAUEjLilL9FKclwbwK7VlXw+h5jMvT2TDFeYFCHM24O1XdnC/on/hx8mxVO3FTQkyHZnOghQ== + dependencies: + traverse-chain "~0.1.0" + flat-cache@^3.0.4: version "3.2.0" resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz" @@ -2938,6 +2976,11 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +json-stringify-safe@~5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + json5@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz" @@ -3070,6 +3113,11 @@ lru-cache@^10.2.0: resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz" integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== +lru-cache@~2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d" + integrity sha512-Q5pAgXs+WEAfoEdw2qKQhNFFhMoFMTYqRVKKUMnzuiR7oKFHS7fWo848cPcTKw+4j/IdN17NyzdhVKgabFV0EA== + lucide-react@^0.408.0: version "0.408.0" resolved "https://registry.npmjs.org/lucide-react/-/lucide-react-0.408.0.tgz" @@ -4389,6 +4437,11 @@ remark-stringify@^11.0.0: mdast-util-to-markdown "^2.0.0" unified "^11.0.0" +request-ip@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/request-ip/-/request-ip-3.3.0.tgz#863451e8fec03847d44f223e30a5d63e369fa611" + integrity sha512-cA6Xh6e0fDBBBwH77SLJaJPBmD3nWVAcF9/XAcsrIHdjhFzFiB5aNQFytdjCGPezU3ROwrR11IddKAM08vohxA== + require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" @@ -4452,6 +4505,21 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" +rollbar@^2.26.4: + version "2.26.4" + resolved "https://registry.yarnpkg.com/rollbar/-/rollbar-2.26.4.tgz#05e47d3b1f52ab6da9f88710ec66371a76cdc3c9" + integrity sha512-JKmrj6riYm9ZPJisgxljgH4uCsvjMHDHXrinDF7aAFaP+eoF51HomVPtLcDTYLsrJ568aKVNLUhedFajONBwSg== + dependencies: + async "~3.2.3" + console-polyfill "0.3.0" + error-stack-parser "^2.0.4" + json-stringify-safe "~5.0.0" + lru-cache "~2.2.1" + request-ip "~3.3.0" + source-map "^0.5.7" + optionalDependencies: + decache "^3.0.5" + rrdom@^2.0.0-alpha.13: version "2.0.0-alpha.17" resolved "https://registry.yarnpkg.com/rrdom/-/rrdom-2.0.0-alpha.17.tgz#c200f21a63bab341caea7f3f2f88d760aa045c3a" @@ -4642,11 +4710,21 @@ source-map-js@^1.0.2, source-map-js@^1.2.1: resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== +source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + space-separated-tokens@^2.0.0: version "2.0.2" resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz" integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== +stackframe@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" + integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== + stop-iteration-iterator@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz" @@ -4936,7 +5014,7 @@ tiny-inflate@^1.0.0, tiny-inflate@^1.0.3: resolved "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz" integrity sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw== -tiny-invariant@^1.0.0: +tiny-invariant@^1.0.0, tiny-invariant@^1.1.0: version "1.3.3" resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz" integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== @@ -4960,6 +5038,11 @@ tr46@~0.0.3: resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== +traverse-chain@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/traverse-chain/-/traverse-chain-0.1.0.tgz#61dbc2d53b69ff6091a12a168fd7d433107e40f1" + integrity sha512-up6Yvai4PYKhpNp5PkYtx50m3KbwQrqDwbuZP/ItyL64YEWHAvH6Md83LFLV/GRSk/BoUVwwgUzX6SOQSbsfAg== + trim-lines@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz"