Skip to content

Commit

Permalink
feat(rollbar): add error boundaries on app and main view (#46)
Browse files Browse the repository at this point in the history
* feat(rollbar): add error boundaries on app and main view

* refactor(rollbar): clean up error handling component

* feat[Rollbar]: improve router logic
  • Loading branch information
ArslanSaleem authored and gventuri committed Oct 29, 2024
1 parent d63513a commit c2d7bed
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 14 deletions.
3 changes: 2 additions & 1 deletion frontend/.env.example
Original file line number Diff line number Diff line change
@@ -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
NEXT_PUBLIC_MIXPANEL_TOKEN=f2e8a71ab2bde33ebf346c5abf6ba9fa
NEXT_PUBLIC_ROLLBAR_ACCESS_TOKEN=0df0bee895044430880278e2b2a5b2d2
2 changes: 2 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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": {
Expand Down
10 changes: 7 additions & 3 deletions frontend/src/app/(app)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -17,9 +19,11 @@ export default function RootLayout({
<Sidebar />
<div className="flex-1 flex flex-col overflow-hidden md:ml-64">
<Navbar />
<main className="flex-1 overflow-x-hidden overflow-y-auto bg-gray-50 px-10 py-6">
{children}
</main>
<ErrorBoundary fallbackUI={ViewErrorFallback}>
<main className="flex-1 overflow-x-hidden overflow-y-auto bg-gray-50 px-10 py-6">
{children}
</main>
</ErrorBoundary>
</div>
</div>
</ScrollProvider>
Expand Down
29 changes: 20 additions & 9 deletions frontend/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -22,14 +29,18 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
<ReactQueryClientProvider>
<html lang="en">
<head />
<body className={inter.className}>
<Toaster position="top-right" />
{children}
</body>
</html>
</ReactQueryClientProvider>
<html lang="en">
<head />
<body className={inter.className}>
<Provider config={rollbarConfig}>
<ErrorBoundary fallbackUI={GlobalErrorFallback}>
<ReactQueryClientProvider>
<Toaster position="top-right" />
{children}
</ReactQueryClientProvider>
</ErrorBoundary>
</Provider>
</body>
</html>
);
}
49 changes: 49 additions & 0 deletions frontend/src/components/ErrorFallback.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"use client";
import React, { useEffect, useState } from "react";
import { Button } from "./ui/Button";
import { usePathname } from "next/navigation";

interface ErrorFallbackProps {
error: Error | null;
resetError: () => void;
}

interface ErrorFallbackBaseProps extends ErrorFallbackProps {
textColor: string;
}

// Fallback UI component displayed on error
const ErrorFallbackBase = ({
error,
resetError,
textColor,
}: ErrorFallbackBaseProps) => {
const pathname = usePathname();
const [initialPathname, setInitialPathname] = useState<string | null>(null);

useEffect(() => {
if (initialPathname === null) {
setInitialPathname(pathname);
} else if (pathname !== initialPathname && error) {
resetError();
}
}, [pathname, initialPathname, error, resetError]);

return (
<div className={`p-8 text-center ${textColor}`}>
<h1>Oops! Something went wrong.</h1>
<p>{error?.message || "We're working on fixing this issue."}</p>
<Button onClick={resetError} className="mt-4">
Try Again
</Button>
</div>
);
};

export const GlobalErrorFallback = (props: ErrorFallbackProps) => (
<ErrorFallbackBase {...props} textColor="text-white" />
);

export const ViewErrorFallback = (props: ErrorFallbackProps) => (
<ErrorFallbackBase {...props} textColor="text-black" />
);
85 changes: 84 additions & 1 deletion frontend/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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==

[email protected]:
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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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==
Expand All @@ -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"
Expand Down

0 comments on commit c2d7bed

Please sign in to comment.