Просмотр исходного кода

Merge pull request #1213 from porter-dev/por-32-add-sentry-to-fe

[POR-32] Add sentry on frontend
abelanger5 4 лет назад
Родитель
Сommit
04145a6945

+ 131 - 0
dashboard/package-lock.json

@@ -2655,6 +2655,137 @@
       "integrity": "sha512-0p1rCgM3LLbAdwBnc7gqgnvjHg9KpbhcSphergHShlkWz8EdPawoMJ3/VbezI0mGC5eKCDzMaPgF9Yca6cKvrg==",
       "dev": true
     },
+    "@sentry/browser": {
+      "version": "6.12.0",
+      "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.12.0.tgz",
+      "integrity": "sha512-wsJi1NLOmfwtPNYxEC50dpDcVY7sdYckzwfqz1/zHrede1mtxpqSw+7iP4bHADOJXuF+ObYYTHND0v38GSXznQ==",
+      "requires": {
+        "@sentry/core": "6.12.0",
+        "@sentry/types": "6.12.0",
+        "@sentry/utils": "6.12.0",
+        "tslib": "^1.9.3"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+        }
+      }
+    },
+    "@sentry/core": {
+      "version": "6.12.0",
+      "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.12.0.tgz",
+      "integrity": "sha512-mU/zdjlzFHzdXDZCPZm8OeCw7c9xsbL49Mq0TrY0KJjLt4CJBkiq5SDTGfRsenBLgTedYhe5Z/J8Z+xVVq+MfQ==",
+      "requires": {
+        "@sentry/hub": "6.12.0",
+        "@sentry/minimal": "6.12.0",
+        "@sentry/types": "6.12.0",
+        "@sentry/utils": "6.12.0",
+        "tslib": "^1.9.3"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+        }
+      }
+    },
+    "@sentry/hub": {
+      "version": "6.12.0",
+      "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.12.0.tgz",
+      "integrity": "sha512-yR/UQVU+ukr42bSYpeqvb989SowIXlKBanU0cqLFDmv5LPCnaQB8PGeXwJAwWhQgx44PARhmB82S6Xor8gYNxg==",
+      "requires": {
+        "@sentry/types": "6.12.0",
+        "@sentry/utils": "6.12.0",
+        "tslib": "^1.9.3"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+        }
+      }
+    },
+    "@sentry/minimal": {
+      "version": "6.12.0",
+      "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.12.0.tgz",
+      "integrity": "sha512-r3C54Q1KN+xIqUvcgX9DlcoWE7ezWvFk2pSu1Ojx9De81hVqR9u5T3sdSAP2Xma+um0zr6coOtDJG4WtYlOtsw==",
+      "requires": {
+        "@sentry/hub": "6.12.0",
+        "@sentry/types": "6.12.0",
+        "tslib": "^1.9.3"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+        }
+      }
+    },
+    "@sentry/react": {
+      "version": "6.12.0",
+      "resolved": "https://registry.npmjs.org/@sentry/react/-/react-6.12.0.tgz",
+      "integrity": "sha512-E8Nw9PPzP/EyMy64ksr9xcyYYlBmUA5ROnkPQp7o5wF0xf5/J+nMS1tQdyPnLQe2KUgHlN4kVs2HHft1m7mSYQ==",
+      "requires": {
+        "@sentry/browser": "6.12.0",
+        "@sentry/minimal": "6.12.0",
+        "@sentry/types": "6.12.0",
+        "@sentry/utils": "6.12.0",
+        "hoist-non-react-statics": "^3.3.2",
+        "tslib": "^1.9.3"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+        }
+      }
+    },
+    "@sentry/tracing": {
+      "version": "6.12.0",
+      "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.12.0.tgz",
+      "integrity": "sha512-u10QHNknPBzbWSUUNMkvuH53sQd5NaBo6YdNPj4p5b7sE7445Sh0PwBpRbY3ZiUUiwyxV59fx9UQ4yVnPGxZQA==",
+      "requires": {
+        "@sentry/hub": "6.12.0",
+        "@sentry/minimal": "6.12.0",
+        "@sentry/types": "6.12.0",
+        "@sentry/utils": "6.12.0",
+        "tslib": "^1.9.3"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+        }
+      }
+    },
+    "@sentry/types": {
+      "version": "6.12.0",
+      "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.12.0.tgz",
+      "integrity": "sha512-urtgLzE4EDMAYQHYdkgC0Ei9QvLajodK1ntg71bGn0Pm84QUpaqpPDfHRU+i6jLeteyC7kWwa5O5W1m/jrjGXA=="
+    },
+    "@sentry/utils": {
+      "version": "6.12.0",
+      "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.12.0.tgz",
+      "integrity": "sha512-oRHQ7TH5TSsJqoP9Gqq25Jvn9LKexXfAh/OoKwjMhYCGKGhqpDNUIZVgl9DWsGw5A5N5xnQyLOxDfyRV5RshdA==",
+      "requires": {
+        "@sentry/types": "6.12.0",
+        "tslib": "^1.9.3"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+        }
+      }
+    },
     "@sheerun/mutationobserver-shim": {
       "version": "0.3.3",
       "resolved": "https://registry.npmjs.org/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz",

+ 2 - 0
dashboard/package.json

@@ -4,6 +4,8 @@
   "private": true,
   "dependencies": {
     "@material-ui/core": "^4.11.3",
+    "@sentry/react": "^6.12.0",
+    "@sentry/tracing": "^6.12.0",
     "@visx/axis": "^1.6.1",
     "@visx/curve": "^1.0.0",
     "@visx/event": "^1.3.0",

+ 2 - 2
dashboard/src/components/UnexpectedErrorPage.tsx

@@ -1,7 +1,7 @@
 import React from "react";
 import styled from "styled-components";
 
-const UnexpectedErrorPage: React.FC = ({ error, resetErrorBoundary }: any) => (
+const UnexpectedErrorPage = ({ error, resetError }: any) => (
   <>
     <StyledPageNotFound>
       <Mega>
@@ -9,7 +9,7 @@ const UnexpectedErrorPage: React.FC = ({ error, resetErrorBoundary }: any) => (
         <Inside>Unknown Error</Inside>
       </Mega>
       <Flex>
-        <BackButton width="140px" onClick={() => resetErrorBoundary(error)}>
+        <BackButton width="140px" onClick={() => resetError(error)}>
           <i className="material-icons">arrow_back</i>
           Reload page
         </BackButton>

+ 4 - 0
dashboard/src/index.tsx

@@ -4,11 +4,15 @@ import "regenerator-runtime/runtime";
 import * as React from "react";
 import * as ReactDOM from "react-dom";
 import App from "./App";
+import { SetupSentry } from "shared/sentry/setup";
 
 declare global {
   interface Window {
     analytics: any;
   }
 }
+if (process.env.ENABLE_SENTRY) {
+  SetupSentry();
+}
 
 ReactDOM.render(<App />, document.getElementById("output"));

+ 14 - 0
dashboard/src/shared/PorterErrorBoundary.tsx

@@ -1,9 +1,12 @@
 import UnexpectedErrorPage from "components/UnexpectedErrorPage";
 import React from "react";
 import { ErrorBoundary } from "react-error-boundary";
+import * as Sentry from "@sentry/react";
 
 export type PorterErrorBoundaryProps<OnResetProps = {}> = {
+  // Component or useful name to describe where the error boundary was setted
   errorBoundaryLocation: string;
+  // Used in case the boundary shouldn't refresh but instead do other action
   onReset?: (props: OnResetProps) => unknown;
 };
 
@@ -13,6 +16,17 @@ const PorterErrorBoundary: React.FC<PorterErrorBoundaryProps> = ({
   children,
 }) => {
   const handleError = (error: Error, info: { componentStack: string }) => {
+    if (process.env.SENTRY_ENABLED) {
+      Sentry.captureException(error, (scope) => {
+        scope.setTags({
+          error_boundary_location: errorBoundaryLocation,
+          error_message: error?.message,
+          component_stack: info?.componentStack,
+        });
+        return scope;
+      });
+    }
+
     window?.analytics?.track("React Error", {
       location: errorBoundaryLocation,
       error: error.message,

+ 17 - 0
dashboard/src/shared/sentry/setup.ts

@@ -0,0 +1,17 @@
+import * as Sentry from "@sentry/react";
+import { Integrations } from "@sentry/tracing";
+
+const SENTRY_DSN = process.env.SENTRY_DSN;
+
+export const SetupSentry = () => {
+  if (!SENTRY_DSN) {
+    return;
+  }
+  Sentry.init({
+    dsn: SENTRY_DSN,
+    integrations: [new Integrations.BrowserTracing()],
+
+    // Check out https://docs.sentry.io/platforms/javascript/guides/react/configuration/sampling/ for a more refined sample rate
+    tracesSampleRate: 0.25,
+  });
+};