PorterErrorBoundary.tsx 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import UnexpectedErrorPage from "components/UnexpectedErrorPage";
  2. import React from "react";
  3. import { ErrorBoundary } from "react-error-boundary";
  4. import * as Sentry from "@sentry/react";
  5. export type PorterErrorBoundaryProps<OnResetProps = {}> = {
  6. // Component or useful name to describe where the error boundary was setted
  7. errorBoundaryLocation: string;
  8. // Used in case the boundary shouldn't refresh but instead do other action
  9. onReset?: (props: OnResetProps) => unknown;
  10. };
  11. const PorterErrorBoundary: React.FC<PorterErrorBoundaryProps> = ({
  12. errorBoundaryLocation,
  13. onReset,
  14. children,
  15. }) => {
  16. const handleError = (error: Error, info: { componentStack: string }) => {
  17. if (process.env.ENABLE_SENTRY) {
  18. Sentry.captureException(error, (scope) => {
  19. scope.setTags({
  20. error_boundary_location: errorBoundaryLocation,
  21. error_message: error?.message,
  22. component_stack: info?.componentStack,
  23. });
  24. return scope;
  25. });
  26. }
  27. window?.analytics?.track("React Error", {
  28. location: errorBoundaryLocation,
  29. error: error.message,
  30. componentStack: info?.componentStack,
  31. url: window.location.toString(),
  32. });
  33. };
  34. const handleOnReset = (props: unknown) => {
  35. typeof onReset === "function" ? onReset(props) : window.location.reload();
  36. };
  37. return (
  38. <ErrorBoundary
  39. onError={handleError}
  40. FallbackComponent={UnexpectedErrorPage}
  41. onReset={handleOnReset}
  42. >
  43. {children}
  44. </ErrorBoundary>
  45. );
  46. };
  47. export default PorterErrorBoundary;