Last active
March 15, 2023 20:26
-
-
Save emeraldsanto/22280c6f0376b74151c0341544beaa5d to your computer and use it in GitHub Desktop.
Custom error boundary with Firebase Crashlytics reporting and HOC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component, ComponentType, ReactNode } from "react"; | |
import crashlytics from "@react-native-firebase/crashlytics"; | |
export interface ErrorBoundaryProps { | |
fallback: () => ReactNode; | |
} | |
/** | |
* Wraps the provided component in an ErrorBoundary, with the provided fallback. | |
* This should be used on components whose parent is not easy to control, such as | |
* a React Navigation screen to be able to catch errors at the highest level, not | |
* only children of said screen. | |
* @param WrappedComponent The component to wrap | |
* @param fallback The component to render on error | |
* | |
* @example | |
* const SomeScreen: NavigationScreen<"SomeRoute"> = props => { | |
* // ... | |
* } | |
* | |
* export default withErrorBoundary(SomeScreen, () => <Text>Oops...</Text>); | |
*/ | |
export function withErrorBoundary<P extends string | number | object>(WrappedComponent: ComponentType<P>, fallback: ErrorBoundaryProps["fallback"]) { | |
return function ComponentWithBoundary(props: P) { | |
return ( | |
<ErrorBoundary fallback={fallback}> | |
<WrappedComponent {...props} /> | |
</ErrorBoundary> | |
); | |
} | |
} | |
/** | |
* Component to be placed as a parent of any other component | |
* which may throw an error during rendering to catch it, | |
* record it to Firebase Crashlytics and display fallback content. | |
* https://reactjs.org/docs/error-boundaries.html | |
*/ | |
export class ErrorBoundary extends Component<ErrorBoundaryProps> { | |
state: { error: Error | undefined } = { | |
error: undefined | |
} | |
componentDidCatch(error: any, errorInfo: any) { | |
this.setState({ error }); | |
crashlytics().recordError(error); | |
} | |
render() { | |
if (!this.state.error) { | |
return this.props.children | |
} | |
return this.props.fallback(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment