Files
ontime/apps/client/src/common/components/error-boundary/ErrorBoundary.jsx
T
Alex Christoffer Rasmussen 7c1d2f4554 refactor: small cleanups (#2059)
* refactor: remove unneeded async

* chore: add express Router type to all routes

* refactor: don't use index in react key

* refactor: correctly get error message in excel route

* refactor: avoid exporting muteable values
2026-04-26 17:32:50 +02:00

81 lines
2.1 KiB
React

// skipcq: JS-C1003 - sentry does not expose itself as an ES Module.
import * as Sentry from '@sentry/react';
import React from 'react';
import { runtimeStore } from '../../stores/runtime';
import { getConnectionState, getReconnectAttempts } from '../../utils/socket';
import style from './ErrorBoundary.module.scss';
class ErrorBoundary extends React.Component {
reportContent = '';
constructor(props) {
super(props);
this.state = { error: null, errorInfo: null };
}
static getDerivedStateFromError(error) {
// Update state so next render shows fallback UI.
return { errorMessage: error.toString() };
}
componentDidCatch(error, info) {
this.setState({
error,
errorInfo: info,
});
this.reportContent = `${error} ${info.componentStack}`;
const appState = runtimeStore.getState();
if (appState.ping < 0) {
return;
}
Sentry.withScope((scope) => {
scope.setExtras({
error,
store: appState,
hasSocket: { hasConnected: getConnectionState(), reconnectAttempts: getReconnectAttempts() },
});
const eventId = Sentry.captureException(error);
this.setState({ eventId, info });
});
}
render() {
if (this.state.errorMessage) {
return (
<div className={style.errorContainer} data-testid='error-container'>
<div>
<p className={style.error}>: /</p>
<p>Something went wrong.</p>
<a
className={style.report}
href={`mailto:mail@getontime.no?subject=Error%20Report&body=${encodeURIComponent(this.reportContent)}`}
>
Report error
</a>
<div
role='button'
className={style.report}
onClick={() => {
if (window?.process?.type === 'renderer') {
window.ipcRenderer.send('reload');
} else {
window.location.reload();
}
}}
>
Reload interface
</div>
</div>
</div>
);
}
return this.props.children;
}
}
export default ErrorBoundary;