UNPKG

react-native-cn-richtext-editor

Version:
95 lines 3.56 kB
import React from 'react'; import { NativeModules, StyleSheet, Text, View } from 'react-native'; import { getAppLoadingLifecycleEmitter } from './AppLoading'; const { ExponentAppLoadingManager } = NativeModules; async function finishedAsync() { if (ExponentAppLoadingManager && ExponentAppLoadingManager.finishedAsync) { return await ExponentAppLoadingManager.finishedAsync(); } } export default class RootErrorBoundary extends React.Component { constructor() { super(...arguments); this.state = { error: null, }; this._appLoadingIsMounted = false; this._subscribeToGlobalErrors = () => { this._appLoadingIsMounted = true; // Bacon: This isn't supported in RNWeb yet let ErrorUtils = global.ErrorUtils; if (!ErrorUtils) return; let originalErrorHandler = ErrorUtils.getGlobalHandler(); ErrorUtils.setGlobalHandler((error, isFatal) => { if (this._appLoadingIsMounted) { finishedAsync(); if (isFatal) { this.setState({ error }); } } originalErrorHandler(error, isFatal); }); }; this._unsubscribeFromGlobalErrors = () => { // We don't remove the global error handler that we set here because it is conceivable that the // user may add error handlers *after* we subscribe, and we don't want to override those, so // instead we just gate the call this._appLoadingIsMounted = false; }; } componentWillMount() { // In production the app will just hard crash on errors, unless the developer decides to handle // them by overriding the global error handler and swallowing the error, in which case they are // responsible for determining how to recover from this state. if (__DEV__) { getAppLoadingLifecycleEmitter().once('componentDidMount', this._subscribeToGlobalErrors); getAppLoadingLifecycleEmitter().once('componentWillUnmount', this._unsubscribeFromGlobalErrors); } } // Test this by adding `throw new Error('example')` to your root component componentDidCatch(error) { if (this._appLoadingIsMounted) { finishedAsync(); this.setState({ error }); } console.error(error); } render() { if (this.state.error) { return (<View style={styles.container}> <Text style={styles.warningIcon}>⚠️</Text> <Text style={[styles.paragraph, { color: '#000' }]}> A fatal error was encountered while rendering the root component. </Text> <Text style={styles.paragraph}> Review your application logs for more information, and reload the app when the issue is resolved. In production, your app would have crashed. </Text> </View>); } else { return this.props.children; } } } const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', }, paragraph: { marginBottom: 10, textAlign: 'center', marginHorizontal: 30, maxWidth: 350, fontSize: 15, color: '#888', }, warningIcon: { fontSize: 40, marginBottom: 20, }, }); //# sourceMappingURL=RootErrorBoundary.js.map