Explorar o código

Added sentry to the error boundary

jnfrati %!s(int64=4) %!d(string=hai) anos
pai
achega
5383b92a7b

+ 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,
+  });
+};