mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-11-15 03:02:17 -05:00
add react wrapper thingy to find crashings
This commit is contained in:
@@ -141,7 +141,7 @@ export default function AdminOverview({ snapshot, socket, runSensitive, onSnapsh
|
|||||||
<label className="flex max-w-md flex-col gap-0.5">
|
<label className="flex max-w-md flex-col gap-0.5">
|
||||||
<span>Container tag</span>
|
<span>Container tag</span>
|
||||||
<input
|
<input
|
||||||
className="rounded border border-slate-600 bg-slate-900 px-2 py-1 text-slate-100"
|
className="field-input w-full"
|
||||||
value={containerTag ?? lifecycle?.selectedTag ?? ''}
|
value={containerTag ?? lifecycle?.selectedTag ?? ''}
|
||||||
placeholder="Enter a tag"
|
placeholder="Enter a tag"
|
||||||
maxLength={128}
|
maxLength={128}
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import { Component } from 'react';
|
||||||
|
|
||||||
|
export default class AppErrorBoundary extends Component {
|
||||||
|
state = { crashed: false, error: null, componentStack: '', copyStatus: '' };
|
||||||
|
|
||||||
|
static getDerivedStateFromError(error) {
|
||||||
|
return { crashed: true, error };
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidCatch(error, info) {
|
||||||
|
this.setState({ componentStack: info.componentStack || '' });
|
||||||
|
}
|
||||||
|
|
||||||
|
getDetails() {
|
||||||
|
const { error, componentStack } = this.state;
|
||||||
|
return [
|
||||||
|
String(error?.message ?? error ?? 'Unknown error'),
|
||||||
|
'JavaScript stack:',
|
||||||
|
error?.stack || 'Unavailable',
|
||||||
|
'React component stack:',
|
||||||
|
componentStack || 'Unavailable',
|
||||||
|
].join('\n\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
copyDetails = async () => {
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(this.getDetails());
|
||||||
|
this.setState({ copyStatus: 'Copied.' });
|
||||||
|
} catch {
|
||||||
|
// Clipboard access may be unavailable on the display device; the text
|
||||||
|
// remains selectable so the error can still be copied manually.
|
||||||
|
this.setState({ copyStatus: 'Copy unavailable. Select the details below to copy manually.' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (!this.state.crashed) return this.props.children;
|
||||||
|
|
||||||
|
// Keep recovery independent of providers and shared UI components: one of
|
||||||
|
// those dependencies may be the reason the application failed.
|
||||||
|
return (
|
||||||
|
<main style={{ backgroundColor: '#b2339f', minHeight: '100vh' }}>
|
||||||
|
<h1>Application crashed</h1>
|
||||||
|
<button type="button" onClick={this.copyDetails}>Copy details</button>
|
||||||
|
<button type="button" onClick={() => window.location.reload()}>Reload</button>
|
||||||
|
{this.state.copyStatus ? <p role="status">{this.state.copyStatus}</p> : null}
|
||||||
|
<pre>{this.getDetails()}</pre>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-1
@@ -22,6 +22,7 @@ import AnalyticsReporter from './analytics/AnalyticsReporter.jsx'
|
|||||||
import PtzAppRoot from './ptz/PtzAppRoot.jsx'
|
import PtzAppRoot from './ptz/PtzAppRoot.jsx'
|
||||||
import OperatingModeRouteSync from './components/OperatingModeRouteSync/index.jsx'
|
import OperatingModeRouteSync from './components/OperatingModeRouteSync/index.jsx'
|
||||||
import InitialSessionOverlay from './components/InitialSessionOverlay/index.jsx'
|
import InitialSessionOverlay from './components/InitialSessionOverlay/index.jsx'
|
||||||
|
import AppErrorBoundary from './components/AppErrorBoundary.jsx'
|
||||||
|
|
||||||
// Reporting and administration carry substantial route-specific libraries.
|
// Reporting and administration carry substantial route-specific libraries.
|
||||||
// Loading each only on its own route keeps charting and JSON Schema tooling out
|
// Loading each only on its own route keeps charting and JSON Schema tooling out
|
||||||
@@ -40,6 +41,7 @@ function lazyRoute(element, label) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createRoot(document.getElementById('root')).render(
|
createRoot(document.getElementById('root')).render(
|
||||||
|
<AppErrorBoundary>
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<SocketProvider>
|
<SocketProvider>
|
||||||
<SessionProvider>
|
<SessionProvider>
|
||||||
@@ -84,5 +86,6 @@ createRoot(document.getElementById('root')).render(
|
|||||||
</TelemetryProvider>
|
</TelemetryProvider>
|
||||||
</SessionProvider>
|
</SessionProvider>
|
||||||
</SocketProvider>
|
</SocketProvider>
|
||||||
</StrictMode>,
|
</StrictMode>
|
||||||
|
</AppErrorBoundary>,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user