A React Native app for the ultimate thinking partner.
1import React, { Component, ErrorInfo, ReactNode } from 'react';
2import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
3
4interface Props {
5 children: ReactNode;
6 fallback?: (error: Error, resetError: () => void) => ReactNode;
7}
8
9interface State {
10 hasError: boolean;
11 error: Error | null;
12}
13
14/**
15 * Error Boundary component to catch and display errors gracefully
16 */
17export class ErrorBoundary extends Component<Props, State> {
18 constructor(props: Props) {
19 super(props);
20 this.state = {
21 hasError: false,
22 error: null,
23 };
24 }
25
26 static getDerivedStateFromError(error: Error): State {
27 return {
28 hasError: true,
29 error,
30 };
31 }
32
33 componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
34 console.error('Error Boundary caught error:', error, errorInfo);
35 // Here you could log to an error reporting service like Sentry
36 }
37
38 resetError = (): void => {
39 this.setState({
40 hasError: false,
41 error: null,
42 });
43 };
44
45 render(): ReactNode {
46 if (this.state.hasError && this.state.error) {
47 if (this.props.fallback) {
48 return this.props.fallback(this.state.error, this.resetError);
49 }
50
51 return (
52 <View style={styles.container}>
53 <View style={styles.content}>
54 <Text style={styles.title}>Oops! Something went wrong</Text>
55 <Text style={styles.message}>{this.state.error.message}</Text>
56 <TouchableOpacity style={styles.button} onPress={this.resetError}>
57 <Text style={styles.buttonText}>Try Again</Text>
58 </TouchableOpacity>
59 </View>
60 </View>
61 );
62 }
63
64 return this.props.children;
65 }
66}
67
68const styles = StyleSheet.create({
69 container: {
70 flex: 1,
71 backgroundColor: '#0a0a0a',
72 justifyContent: 'center',
73 alignItems: 'center',
74 padding: 20,
75 },
76 content: {
77 alignItems: 'center',
78 maxWidth: 400,
79 },
80 title: {
81 fontSize: 24,
82 fontWeight: '600',
83 color: '#ffffff',
84 marginBottom: 12,
85 textAlign: 'center',
86 },
87 message: {
88 fontSize: 16,
89 color: '#999999',
90 marginBottom: 24,
91 textAlign: 'center',
92 lineHeight: 24,
93 },
94 button: {
95 backgroundColor: '#ffffff',
96 paddingHorizontal: 24,
97 paddingVertical: 12,
98 borderRadius: 8,
99 },
100 buttonText: {
101 fontSize: 16,
102 fontWeight: '600',
103 color: '#0a0a0a',
104 },
105});