fix(ui): sooth honeybader
Changes our error reporting strategy for Honeybadger from "report everything logged by `console.error`" to "report everything caught by an error boundary". As before, Honeybadger still reports everything caught by `window.onerror` as well.pull/14584/head
parent
7d9ec64eec
commit
6d5ac71543
|
@ -1,31 +0,0 @@
|
|||
import _ from 'lodash'
|
||||
import HoneyBadger from 'honeybadger-js'
|
||||
import {GIT_SHA} from 'src/shared/constants'
|
||||
|
||||
if (process.env.CLOUD === 'true') {
|
||||
HoneyBadger.configure({
|
||||
apiKey: process.env.HONEYBADGER_KEY,
|
||||
revision: GIT_SHA,
|
||||
environment: process.env.HONEYBADGER_ENV,
|
||||
})
|
||||
|
||||
const override = () => {
|
||||
if (!window || !window.console) {
|
||||
return
|
||||
}
|
||||
|
||||
const logError = console.error
|
||||
|
||||
console.error = function(...args) {
|
||||
args.forEach(arg => {
|
||||
if (_.isError(arg)) {
|
||||
HoneyBadger.notify(arg)
|
||||
}
|
||||
})
|
||||
|
||||
logError.apply(console, args)
|
||||
}
|
||||
}
|
||||
|
||||
override()
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import 'babel-polyfill'
|
||||
import 'src/cloud/utils/overrides'
|
||||
import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'
|
||||
|
||||
import React, {PureComponent} from 'react'
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
// Libraries
|
||||
import React, {Component} from 'react'
|
||||
import React, {Component, ErrorInfo} from 'react'
|
||||
|
||||
// Components
|
||||
import DefaultErrorMessage from 'src/shared/components/DefaultErrorMessage'
|
||||
|
||||
// Utils
|
||||
import {reportError, parseComponentName} from 'src/shared/utils/errors'
|
||||
|
||||
// Types
|
||||
import {ErrorMessageComponent} from 'src/types'
|
||||
|
||||
|
@ -24,6 +27,10 @@ class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|||
return {error}
|
||||
}
|
||||
|
||||
public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
||||
reportError(error, {component: parseComponentName(errorInfo)})
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {error} = this.state
|
||||
|
||||
|
|
|
@ -4,11 +4,14 @@ tslint:disable max-classes-per-file
|
|||
*/
|
||||
|
||||
// Libraries
|
||||
import React, {Component} from 'react'
|
||||
import React, {Component, ErrorInfo} from 'react'
|
||||
|
||||
// Components
|
||||
import DefaultErrorMessage from 'src/shared/components/DefaultErrorMessage'
|
||||
|
||||
// Utils
|
||||
import {reportError, parseComponentName} from 'src/shared/utils/errors'
|
||||
|
||||
// Types
|
||||
import {ErrorMessageComponent} from 'src/types'
|
||||
|
||||
|
@ -23,9 +26,11 @@ export function ErrorHandlingWith(Error: ErrorMessageComponent) {
|
|||
|
||||
private error: Error = null
|
||||
|
||||
public componentDidCatch(error) {
|
||||
public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
||||
this.error = error
|
||||
this.forceUpdate()
|
||||
|
||||
reportError(error, {component: parseComponentName(errorInfo)})
|
||||
}
|
||||
|
||||
public render() {
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
import {ErrorInfo} from 'react'
|
||||
import HoneyBadger from 'honeybadger-js'
|
||||
import {CLOUD, GIT_SHA} from 'src/shared/constants'
|
||||
|
||||
if (CLOUD) {
|
||||
HoneyBadger.configure({
|
||||
apiKey: process.env.HONEYBADGER_KEY,
|
||||
revision: GIT_SHA,
|
||||
environment: process.env.HONEYBADGER_ENV,
|
||||
})
|
||||
}
|
||||
|
||||
interface AdditionalOptions {
|
||||
component?: string
|
||||
}
|
||||
|
||||
export const reportError = (
|
||||
error: Error,
|
||||
additionalOptions?: AdditionalOptions
|
||||
): void => {
|
||||
if (CLOUD) {
|
||||
HoneyBadger.notify(error, additionalOptions)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Parse React's error boundary info message to provide the name of the
|
||||
component an error occured in.
|
||||
|
||||
For example, given the following info message:
|
||||
|
||||
The above error occurred in the <MePage> component:
|
||||
in MePage (created by ErrorBoundary(MePage))
|
||||
in ErrorBoundary (created by ErrorBoundary(MePage))
|
||||
in ErrorBoundary(MePage) (created by Connect(ErrorBoundary(MePage)))
|
||||
in Connect(ErrorBoundary(MePage)) (created by RouterContext)
|
||||
in SpinnerContainer (created by SetOrg)
|
||||
...
|
||||
|
||||
We will extract "MePage" as the component name.
|
||||
*/
|
||||
export const parseComponentName = (errorInfo: ErrorInfo): string => {
|
||||
const componentName = errorInfo.componentStack
|
||||
.trim()
|
||||
.split('\n')
|
||||
.map(s => s.split(' ')[1])[0]
|
||||
|
||||
return componentName
|
||||
}
|
Loading…
Reference in New Issue