Skip to content

Commit c2d7bed

Browse files
ArslanSaleemgventuri
authored andcommitted
feat(rollbar): add error boundaries on app and main view (#46)
* feat(rollbar): add error boundaries on app and main view * refactor(rollbar): clean up error handling component * feat[Rollbar]: improve router logic
1 parent d63513a commit c2d7bed

File tree

6 files changed

+164
-14
lines changed

6 files changed

+164
-14
lines changed

frontend/.env.example

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
NEXT_PUBLIC_API_URL=http://localhost:3000/api/v1
22
NEXT_PUBLIC_STORAGE_URL=http://localhost:3000/api/assets
3-
NEXT_PUBLIC_MIXPANEL_TOKEN=f2e8a71ab2bde33ebf346c5abf6ba9fa
3+
NEXT_PUBLIC_MIXPANEL_TOKEN=f2e8a71ab2bde33ebf346c5abf6ba9fa
4+
NEXT_PUBLIC_ROLLBAR_ACCESS_TOKEN=0df0bee895044430880278e2b2a5b2d2

frontend/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"@radix-ui/react-context-menu": "^2.2.1",
1717
"@radix-ui/react-radio-group": "^1.2.0",
1818
"@react-pdf/renderer": "^4.0.0",
19+
"@rollbar/react": "^0.12.0-beta",
1920
"@tanstack/react-query": "^5.51.1",
2021
"@tippyjs/react": "^4.2.6",
2122
"@types/mixpanel-browser": "^2.50.1",
@@ -39,6 +40,7 @@
3940
"react-quill": "^2.0.0",
4041
"rehype-sanitize": "^6.0.0",
4142
"remark-gfm": "^4.0.0",
43+
"rollbar": "^2.26.4",
4244
"tailwind-merge": "^2.4.0"
4345
},
4446
"devDependencies": {

frontend/src/app/(app)/layout.tsx

+7-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { ScrollProvider } from "@/context/ScrollContext";
44
import Sidebar from "@/components/ui/Sidebar";
55
import Navbar from "@/components/ui/Navbar";
66
import "@/app/style/globals.css";
7+
import { ErrorBoundary } from "@rollbar/react";
8+
import { ViewErrorFallback } from "@/components/ErrorFallback";
79

810
export default function RootLayout({
911
children,
@@ -17,9 +19,11 @@ export default function RootLayout({
1719
<Sidebar />
1820
<div className="flex-1 flex flex-col overflow-hidden md:ml-64">
1921
<Navbar />
20-
<main className="flex-1 overflow-x-hidden overflow-y-auto bg-gray-50 px-10 py-6">
21-
{children}
22-
</main>
22+
<ErrorBoundary fallbackUI={ViewErrorFallback}>
23+
<main className="flex-1 overflow-x-hidden overflow-y-auto bg-gray-50 px-10 py-6">
24+
{children}
25+
</main>
26+
</ErrorBoundary>
2327
</div>
2428
</div>
2529
</ScrollProvider>

frontend/src/app/layout.tsx

+20-9
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,16 @@ import React from "react";
44
import { ReactQueryClientProvider } from "@/components/ReactQueryClientProvider";
55
import { Toaster } from "react-hot-toast";
66
import "@/app/style/globals.css";
7+
import { Provider, ErrorBoundary } from "@rollbar/react";
8+
import { GlobalErrorFallback } from "@/components/ErrorFallback";
79

810
const inter = Inter({ subsets: ["latin"] });
911

12+
const rollbarConfig = {
13+
accessToken: process.env.NEXT_PUBLIC_ROLLBAR_ACCESS_TOKEN,
14+
environment: process.env.NODE_ENV ?? "production",
15+
};
16+
1017
export const metadata: Metadata = {
1118
title: "PandaETL",
1219
description:
@@ -22,14 +29,18 @@ export default function RootLayout({
2229
children: React.ReactNode;
2330
}>) {
2431
return (
25-
<ReactQueryClientProvider>
26-
<html lang="en">
27-
<head />
28-
<body className={inter.className}>
29-
<Toaster position="top-right" />
30-
{children}
31-
</body>
32-
</html>
33-
</ReactQueryClientProvider>
32+
<html lang="en">
33+
<head />
34+
<body className={inter.className}>
35+
<Provider config={rollbarConfig}>
36+
<ErrorBoundary fallbackUI={GlobalErrorFallback}>
37+
<ReactQueryClientProvider>
38+
<Toaster position="top-right" />
39+
{children}
40+
</ReactQueryClientProvider>
41+
</ErrorBoundary>
42+
</Provider>
43+
</body>
44+
</html>
3445
);
3546
}
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
"use client";
2+
import React, { useEffect, useState } from "react";
3+
import { Button } from "./ui/Button";
4+
import { usePathname } from "next/navigation";
5+
6+
interface ErrorFallbackProps {
7+
error: Error | null;
8+
resetError: () => void;
9+
}
10+
11+
interface ErrorFallbackBaseProps extends ErrorFallbackProps {
12+
textColor: string;
13+
}
14+
15+
// Fallback UI component displayed on error
16+
const ErrorFallbackBase = ({
17+
error,
18+
resetError,
19+
textColor,
20+
}: ErrorFallbackBaseProps) => {
21+
const pathname = usePathname();
22+
const [initialPathname, setInitialPathname] = useState<string | null>(null);
23+
24+
useEffect(() => {
25+
if (initialPathname === null) {
26+
setInitialPathname(pathname);
27+
} else if (pathname !== initialPathname && error) {
28+
resetError();
29+
}
30+
}, [pathname, initialPathname, error, resetError]);
31+
32+
return (
33+
<div className={`p-8 text-center ${textColor}`}>
34+
<h1>Oops! Something went wrong.</h1>
35+
<p>{error?.message || "We're working on fixing this issue."}</p>
36+
<Button onClick={resetError} className="mt-4">
37+
Try Again
38+
</Button>
39+
</div>
40+
);
41+
};
42+
43+
export const GlobalErrorFallback = (props: ErrorFallbackProps) => (
44+
<ErrorFallbackBase {...props} textColor="text-white" />
45+
);
46+
47+
export const ViewErrorFallback = (props: ErrorFallbackProps) => (
48+
<ErrorFallbackBase {...props} textColor="text-black" />
49+
);

frontend/yarn.lock

+84-1
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,13 @@
685685
resolved "https://registry.npmjs.org/@react-types/shared/-/shared-3.24.1.tgz"
686686
integrity sha512-AUQeGYEm/zDTN6zLzdXolDxz3Jk5dDL7f506F07U8tBwxNNI3WRdhU84G0/AaFikOZzDXhOZDr3MhQMzyE7Ydw==
687687

688+
"@rollbar/react@^0.12.0-beta":
689+
version "0.12.0-beta"
690+
resolved "https://registry.yarnpkg.com/@rollbar/react/-/react-0.12.0-beta.tgz#b80dfab1535ece358a0e98a4f26aadee8b54edda"
691+
integrity sha512-8udBX0lJwdBBq+O/jqDXpg/giHt8bo/Us1IlTkHEdCBO18Cjj7sxWJ80OPFxiPRNwZgZnhf2HbxQxvLN+4FeJA==
692+
dependencies:
693+
tiny-invariant "^1.1.0"
694+
688695
"@rrweb/types@^2.0.0-alpha.13":
689696
version "2.0.0-alpha.17"
690697
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:
11691176
resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz"
11701177
integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==
11711178

1179+
async@~3.2.3:
1180+
version "3.2.6"
1181+
resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce"
1182+
integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==
1183+
11721184
asynckit@^0.4.0:
11731185
version "0.4.0"
11741186
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:
14601472
resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz"
14611473
integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==
14621474

1475+
1476+
version "0.3.0"
1477+
resolved "https://registry.yarnpkg.com/console-polyfill/-/console-polyfill-0.3.0.tgz#84900902a18c47a5eba932be75fa44d23e8af861"
1478+
integrity sha512-w+JSDZS7XML43Xnwo2x5O5vxB0ID7T5BdqDtyqT6uiCAX2kZAgcWxNaGqT97tZfSHzfOcvrfsDAodKcJ3UvnXQ==
1479+
14631480
cross-fetch@^3.1.5:
14641481
version "3.1.8"
14651482
resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz"
@@ -1542,6 +1559,13 @@ debug@^3.2.7:
15421559
dependencies:
15431560
ms "^2.1.1"
15441561

1562+
decache@^3.0.5:
1563+
version "3.1.0"
1564+
resolved "https://registry.yarnpkg.com/decache/-/decache-3.1.0.tgz#4f5036fbd6581fcc97237ac3954a244b9536c2da"
1565+
integrity sha512-p7D6wJ5EJFFq1CcF2lu1XeqKFLBob8jRQGNAvFLTsV3CbSKBl3VtliAVlUIGz2i9H6kEFnI2Amaft5ZopIG2Fw==
1566+
dependencies:
1567+
find "^0.2.4"
1568+
15451569
decode-named-character-reference@^1.0.0:
15461570
version "1.0.2"
15471571
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:
17161740
resolved "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz"
17171741
integrity sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==
17181742

1743+
error-stack-parser@^2.0.4:
1744+
version "2.1.4"
1745+
resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286"
1746+
integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==
1747+
dependencies:
1748+
stackframe "^1.3.4"
1749+
17191750
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:
17201751
version "1.23.3"
17211752
resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz"
@@ -2177,6 +2208,13 @@ find-up@^5.0.0:
21772208
locate-path "^6.0.0"
21782209
path-exists "^4.0.0"
21792210

2211+
find@^0.2.4:
2212+
version "0.2.9"
2213+
resolved "https://registry.yarnpkg.com/find/-/find-0.2.9.tgz#4b73f1ff9e56ad91b76e716407fe5ffe6554bb8c"
2214+
integrity sha512-7a4/LCiInB9xYMnAUEjLilL9FKclwbwK7VlXw+h5jMvT2TDFeYFCHM24O1XdnC/on/hx8mxVO3FTQkyHZnOghQ==
2215+
dependencies:
2216+
traverse-chain "~0.1.0"
2217+
21802218
flat-cache@^3.0.4:
21812219
version "3.2.0"
21822220
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:
29382976
resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz"
29392977
integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
29402978

2979+
json-stringify-safe@~5.0.0:
2980+
version "5.0.1"
2981+
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
2982+
integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
2983+
29412984
json5@^1.0.2:
29422985
version "1.0.2"
29432986
resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz"
@@ -3070,6 +3113,11 @@ lru-cache@^10.2.0:
30703113
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz"
30713114
integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==
30723115

3116+
lru-cache@~2.2.1:
3117+
version "2.2.4"
3118+
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d"
3119+
integrity sha512-Q5pAgXs+WEAfoEdw2qKQhNFFhMoFMTYqRVKKUMnzuiR7oKFHS7fWo848cPcTKw+4j/IdN17NyzdhVKgabFV0EA==
3120+
30733121
lucide-react@^0.408.0:
30743122
version "0.408.0"
30753123
resolved "https://registry.npmjs.org/lucide-react/-/lucide-react-0.408.0.tgz"
@@ -4389,6 +4437,11 @@ remark-stringify@^11.0.0:
43894437
mdast-util-to-markdown "^2.0.0"
43904438
unified "^11.0.0"
43914439

4440+
request-ip@~3.3.0:
4441+
version "3.3.0"
4442+
resolved "https://registry.yarnpkg.com/request-ip/-/request-ip-3.3.0.tgz#863451e8fec03847d44f223e30a5d63e369fa611"
4443+
integrity sha512-cA6Xh6e0fDBBBwH77SLJaJPBmD3nWVAcF9/XAcsrIHdjhFzFiB5aNQFytdjCGPezU3ROwrR11IddKAM08vohxA==
4444+
43924445
require-from-string@^2.0.2:
43934446
version "2.0.2"
43944447
resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
@@ -4452,6 +4505,21 @@ rimraf@^3.0.2:
44524505
dependencies:
44534506
glob "^7.1.3"
44544507

4508+
rollbar@^2.26.4:
4509+
version "2.26.4"
4510+
resolved "https://registry.yarnpkg.com/rollbar/-/rollbar-2.26.4.tgz#05e47d3b1f52ab6da9f88710ec66371a76cdc3c9"
4511+
integrity sha512-JKmrj6riYm9ZPJisgxljgH4uCsvjMHDHXrinDF7aAFaP+eoF51HomVPtLcDTYLsrJ568aKVNLUhedFajONBwSg==
4512+
dependencies:
4513+
async "~3.2.3"
4514+
console-polyfill "0.3.0"
4515+
error-stack-parser "^2.0.4"
4516+
json-stringify-safe "~5.0.0"
4517+
lru-cache "~2.2.1"
4518+
request-ip "~3.3.0"
4519+
source-map "^0.5.7"
4520+
optionalDependencies:
4521+
decache "^3.0.5"
4522+
44554523
rrdom@^2.0.0-alpha.13:
44564524
version "2.0.0-alpha.17"
44574525
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:
46424710
resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz"
46434711
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
46444712

4713+
source-map@^0.5.7:
4714+
version "0.5.7"
4715+
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
4716+
integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
4717+
46454718
space-separated-tokens@^2.0.0:
46464719
version "2.0.2"
46474720
resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz"
46484721
integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==
46494722

4723+
stackframe@^1.3.4:
4724+
version "1.3.4"
4725+
resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310"
4726+
integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==
4727+
46504728
stop-iteration-iterator@^1.0.0:
46514729
version "1.0.0"
46524730
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:
49365014
resolved "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz"
49375015
integrity sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==
49385016

4939-
tiny-invariant@^1.0.0:
5017+
tiny-invariant@^1.0.0, tiny-invariant@^1.1.0:
49405018
version "1.3.3"
49415019
resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz"
49425020
integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==
@@ -4960,6 +5038,11 @@ tr46@~0.0.3:
49605038
resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz"
49615039
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
49625040

5041+
traverse-chain@~0.1.0:
5042+
version "0.1.0"
5043+
resolved "https://registry.yarnpkg.com/traverse-chain/-/traverse-chain-0.1.0.tgz#61dbc2d53b69ff6091a12a168fd7d433107e40f1"
5044+
integrity sha512-up6Yvai4PYKhpNp5PkYtx50m3KbwQrqDwbuZP/ItyL64YEWHAvH6Md83LFLV/GRSk/BoUVwwgUzX6SOQSbsfAg==
5045+
49635046
trim-lines@^3.0.0:
49645047
version "3.0.1"
49655048
resolved "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz"

0 commit comments

Comments
 (0)