{"version":3,"file":"ErrorBoundary.mjs","sources":["../../../../src/components/ErrorBoundary/ErrorBoundary.tsx"],"sourcesContent":["import { PureComponent, ReactNode, ComponentType, ErrorInfo } from 'react';\n\nimport { faro } from '@grafana/faro-web-sdk';\n\nimport { Alert } from '../Alert/Alert';\n\nimport { ErrorWithStack } from './ErrorWithStack';\n\nexport type { ErrorInfo };\n\nexport interface ErrorBoundaryApi {\n  error: Error | null;\n  errorInfo: ErrorInfo | null;\n}\n\ninterface Props {\n  children: (r: ErrorBoundaryApi) => ReactNode;\n  /** Will re-render children after error if recover values changes */\n  dependencies?: unknown[];\n  /** Callback called on error */\n  onError?: (error: Error) => void;\n  /** Callback error state is cleared due to recover props change */\n  onRecover?: () => void;\n  /** Default error logger - Faro by default */\n  errorLogger?: (error: Error) => void;\n}\n\ninterface State {\n  error: Error | null;\n  errorInfo: ErrorInfo | null;\n}\n\nexport class ErrorBoundary extends PureComponent<Props, State> {\n  readonly state: State = {\n    error: null,\n    errorInfo: null,\n  };\n\n  componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n    const logger = this.props.errorLogger ?? faro?.api?.pushError;\n\n    if (logger) {\n      logger(error);\n    }\n\n    this.setState({ error, errorInfo });\n\n    if (this.props.onError) {\n      this.props.onError(error);\n    }\n  }\n\n  componentDidUpdate(prevProps: Props) {\n    const { dependencies, onRecover } = this.props;\n\n    if (this.state.error) {\n      if (dependencies && prevProps.dependencies) {\n        for (let i = 0; i < dependencies.length; i++) {\n          if (dependencies[i] !== prevProps.dependencies[i]) {\n            this.setState({ error: null, errorInfo: null });\n            if (onRecover) {\n              onRecover();\n            }\n            break;\n          }\n        }\n      }\n    }\n  }\n\n  render() {\n    const { children } = this.props;\n    const { error, errorInfo } = this.state;\n\n    return children({\n      error,\n      errorInfo,\n    });\n  }\n}\n\n/**\n * Props for the ErrorBoundaryAlert component\n *\n * @public\n */\nexport interface ErrorBoundaryAlertProps {\n  /** Title for the error boundary alert */\n  title?: string;\n\n  /** Component to be wrapped with an error boundary */\n  children: ReactNode;\n\n  /** 'page' will render full page error with stacktrace. 'alertbox' will render an <Alert />. Default 'alertbox' */\n  style?: 'page' | 'alertbox';\n\n  /** Will re-render children after error if recover values changes */\n  dependencies?: unknown[];\n  /** Default error logger - Faro by default */\n  errorLogger?: (error: Error) => void;\n}\n\nexport class ErrorBoundaryAlert extends PureComponent<ErrorBoundaryAlertProps> {\n  static defaultProps: Partial<ErrorBoundaryAlertProps> = {\n    title: 'An unexpected error happened',\n    style: 'alertbox',\n  };\n\n  render() {\n    const { title, children, style, dependencies, errorLogger } = this.props;\n\n    return (\n      <ErrorBoundary dependencies={dependencies} errorLogger={errorLogger}>\n        {({ error, errorInfo }) => {\n          if (!errorInfo) {\n            return children;\n          }\n\n          if (style === 'alertbox') {\n            return (\n              <Alert title={title || ''}>\n                <details style={{ whiteSpace: 'pre-wrap' }}>\n                  {error && error.toString()}\n                  <br />\n                  {errorInfo.componentStack}\n                </details>\n              </Alert>\n            );\n          }\n\n          return <ErrorWithStack title={title || ''} error={error} errorInfo={errorInfo} />;\n        }}\n      </ErrorBoundary>\n    );\n  }\n}\n\n/**\n * HOC for wrapping a component in an error boundary.\n *\n * @param Component - the react component to wrap in error boundary\n * @param errorBoundaryProps - error boundary options\n *\n * @public\n */\nexport function withErrorBoundary<P extends {} = {}>(\n  Component: ComponentType<P>,\n  errorBoundaryProps: Omit<ErrorBoundaryAlertProps, 'children'> = {}\n): ComponentType<P> {\n  const comp = (props: P) => (\n    <ErrorBoundaryAlert {...errorBoundaryProps}>\n      <Component {...props} />\n    </ErrorBoundaryAlert>\n  );\n  comp.displayName = 'WithErrorBoundary';\n\n  return comp;\n}\n"],"names":[],"mappings":"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"}