larxius commited on
Commit
7214c09
·
verified ·
1 Parent(s): f6c5cad

Update frontend/src/components/ErrorBoundary.jsx

Browse files
frontend/src/components/ErrorBoundary.jsx CHANGED
@@ -1 +1,68 @@
1
- import React from 'react'; export class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false, error: null }; } static getDerivedStateFromError(error) { return { hasError: true, error }; } render() { if (this.state.hasError) { return <div style={{padding: '20px', color: 'red'}}><pre>{this.state.error.toString()}</pre><pre>{this.state.error.stack}</pre></div>; } return this.props.children; } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+
3
+ export class ErrorBoundary extends React.Component {
4
+ constructor(props) {
5
+ super(props);
6
+ this.state = { hasError: false, error: null };
7
+ }
8
+
9
+ static getDerivedStateFromError(error) {
10
+ return { hasError: true, error };
11
+ }
12
+
13
+ componentDidCatch(error, errorInfo) {
14
+ console.error("Uncaught Error caught by ErrorBoundary:", error, errorInfo);
15
+ // If it's a chunk loading error (common during SPA back-navigation with lazy routes), auto-reload page once
16
+ if (error && (error.name === 'ChunkLoadError' || error.message?.includes('dynamically imported module') || error.message?.includes('Importing a module script failed'))) {
17
+ const hasReloaded = sessionStorage.getItem('chunk_reload_retry');
18
+ if (!hasReloaded) {
19
+ sessionStorage.setItem('chunk_reload_retry', 'true');
20
+ window.location.reload();
21
+ }
22
+ }
23
+ }
24
+
25
+ componentDidMount() {
26
+ sessionStorage.removeItem('chunk_reload_retry');
27
+ window.addEventListener('popstate', this.handlePopState);
28
+ }
29
+
30
+ componentWillUnmount() {
31
+ window.removeEventListener('popstate', this.handlePopState);
32
+ }
33
+
34
+ handlePopState = () => {
35
+ if (this.state.hasError) {
36
+ this.setState({ hasError: false, error: null });
37
+ }
38
+ };
39
+
40
+ render() {
41
+ if (this.state.hasError) {
42
+ return (
43
+ <div className="min-h-screen flex flex-col items-center justify-center bg-slate-50 p-6 text-center font-sans">
44
+ <div className="bg-white border border-slate-200 shadow-xl rounded-2xl p-8 max-w-md w-full animate-fade-in">
45
+ <div className="w-12 h-12 rounded-full bg-blue-50 text-blue-600 flex items-center justify-center mx-auto mb-4">
46
+ <span className="material-symbols-outlined text-2xl">refresh</span>
47
+ </div>
48
+ <h2 className="text-xl font-bold text-slate-900 mb-2">Session Navigation Update</h2>
49
+ <p className="text-sm text-slate-500 mb-6 leading-relaxed">
50
+ The page view needs a quick refresh to synchronize your security session.
51
+ </p>
52
+ <button
53
+ onClick={() => {
54
+ this.setState({ hasError: false, error: null });
55
+ window.location.reload();
56
+ }}
57
+ className="w-full bg-blue-600 hover:bg-blue-700 text-white font-semibold py-3 px-6 rounded-xl transition-all shadow-md shadow-blue-600/20 border-0 cursor-pointer text-sm"
58
+ >
59
+ Refresh Page
60
+ </button>
61
+ </div>
62
+ </div>
63
+ );
64
+ }
65
+
66
+ return this.props.children;
67
+ }
68
+ }