@oxyhq/services
Version:
Reusable OxyHQ module to handle authentication, user management, karma system, device-based session management and more 🚀
139 lines (135 loc) • 3.4 kB
JavaScript
"use strict";
import React, { Component } from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/**
* Error Boundary Component
*
* Catches JavaScript errors anywhere in the child component tree,
* logs those errors, and displays a fallback UI instead of crashing.
*
* Usage:
* <ErrorBoundary>
* <YourComponent />
* </ErrorBoundary>
*/
export class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
error: null,
errorInfo: null
};
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI
return {
hasError: true,
error
};
}
componentDidCatch(error, errorInfo) {
// Log error to console in development
if (__DEV__) {
console.error('ErrorBoundary caught an error:', error, errorInfo);
}
// Call optional error handler
if (this.props.onError) {
this.props.onError(error, errorInfo);
}
// Update state with error info
this.setState({
error,
errorInfo
});
}
handleReset = () => {
this.setState({
hasError: false,
error: null,
errorInfo: null
});
};
render() {
if (this.state.hasError) {
// Use custom fallback if provided
if (this.props.fallback) {
return this.props.fallback;
}
// Default fallback UI
return /*#__PURE__*/_jsx(View, {
style: styles.container,
children: /*#__PURE__*/_jsxs(View, {
style: styles.errorContainer,
children: [/*#__PURE__*/_jsx(Text, {
style: styles.errorTitle,
children: "Something went wrong"
}), /*#__PURE__*/_jsx(Text, {
style: styles.errorMessage,
children: this.state.error?.message || 'An unexpected error occurred'
}), __DEV__ && this.state.errorInfo && /*#__PURE__*/_jsx(Text, {
style: styles.errorDetails,
children: this.state.errorInfo.componentStack
}), /*#__PURE__*/_jsx(TouchableOpacity, {
style: styles.resetButton,
onPress: this.handleReset,
children: /*#__PURE__*/_jsx(Text, {
style: styles.resetButtonText,
children: "Try Again"
})
})]
})
});
}
return this.props.children;
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: '#fff'
},
errorContainer: {
maxWidth: 400,
width: '100%',
padding: 20,
borderRadius: 8,
backgroundColor: '#f5f5f5',
borderWidth: 1,
borderColor: '#e0e0e0'
},
errorTitle: {
fontSize: 20,
fontWeight: 'bold',
marginBottom: 10,
color: '#d32f2f'
},
errorMessage: {
fontSize: 14,
marginBottom: 15,
color: '#666'
},
errorDetails: {
fontSize: 12,
marginBottom: 15,
color: '#999',
fontFamily: 'monospace'
},
resetButton: {
backgroundColor: '#007AFF',
padding: 12,
borderRadius: 6,
alignItems: 'center'
},
resetButtonText: {
color: '#fff',
fontSize: 16,
fontWeight: '600'
}
});
export default ErrorBoundary;
//# sourceMappingURL=ErrorBoundary.js.map