-
Notifications
You must be signed in to change notification settings - Fork 14
/
GlobalErrorHandler.js
71 lines (60 loc) · 2.02 KB
/
GlobalErrorHandler.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import React from 'react'
import PropTypes from 'prop-types'
import { captureException, showReportDialog } from '@sentry/browser'
import GenericError from './components/Errors/GenericError'
import GlobalErrorScreen from './components/Errors/GlobalErrorScreen'
import DisputeNotFoundError from './components/Disputes/DisputeNotFoundError'
import { DisputeNotFound } from './errors'
import { sentryEnabled } from './sentry'
class GlobalErrorHandler extends React.Component {
static propTypes = {
children: PropTypes.node,
}
state = { error: null, errorStack: null }
componentDidCatch(error, errorInfo) {
this.setState({
error,
errorStack: errorInfo.componentStack
.replace(/^\n+|\n+$/g, '')
.replace(/^ {4}/gm, ''),
})
// Once this point is reached, the app can not recover because the routing
// system, being below this component in the tree, is not functional
// anymore. To make hash changes work despite this (e.g. by pressing the
// back button in the browser), the page need to be reloaded.
window.removeEventListener('hashchange', this.handleHashchange)
window.addEventListener('hashchange', this.handleHashchange)
}
componentWillUnmount() {
window.removeEventListener('hashchange', this.handleHashchange)
}
handleReportClick = () => {
if (sentryEnabled) {
const eventId = captureException(this.state.error)
showReportDialog({ eventId })
}
}
handleHashchange = () => {
window.location.reload()
}
render() {
const { children } = this.props
const { error, errorStack } = this.state
return error ? (
<GlobalErrorScreen>
{error instanceof DisputeNotFound ? (
<DisputeNotFoundError disputeId={error.disputeId} />
) : (
<GenericError
detailsTitle={error.message}
detailsContent={errorStack}
reportCallback={this.handleReportClick}
/>
)}
</GlobalErrorScreen>
) : (
children
)
}
}
export default GlobalErrorHandler