diff --git a/ui/src/organizations/actions/orgs.ts b/ui/src/organizations/actions/orgs.ts index b441c26f4d..219cafe5f3 100644 --- a/ui/src/organizations/actions/orgs.ts +++ b/ui/src/organizations/actions/orgs.ts @@ -2,6 +2,7 @@ import {Dispatch} from 'redux' import {ThunkAction} from 'redux-thunk' import {push, RouterAction} from 'react-router-redux' +import HoneyBadger from 'honeybadger-js' // APIs import {getErrorMessage} from 'src/utils/api' @@ -80,6 +81,9 @@ export interface SetOrg { } export const setOrg = (org: Organization): SetOrg => { + HoneyBadger.setContext({ + orgID: org.id, + }) return { type: ActionTypes.SetOrg, payload: {org}, diff --git a/ui/src/shared/actions/me.ts b/ui/src/shared/actions/me.ts index 608f4a7cb6..96e661214a 100644 --- a/ui/src/shared/actions/me.ts +++ b/ui/src/shared/actions/me.ts @@ -1,5 +1,6 @@ import {MeState} from 'src/shared/reducers/me' import {client} from 'src/utils/api' +import HoneyBadger from 'honeybadger-js' export enum ActionTypes { SetMe = 'SET_ME', @@ -25,8 +26,12 @@ export const getMe = () => async dispatch => { try { const user = await client.users.me() + HoneyBadger.setContext({ + user_id: user.id, + }) + dispatch(setMe(user)) - } catch (e) { - console.error(e) + } catch (error) { + console.error(error) } } diff --git a/ui/src/shared/utils/errors.ts b/ui/src/shared/utils/errors.ts index 580fc37636..02d39d92b8 100644 --- a/ui/src/shared/utils/errors.ts +++ b/ui/src/shared/utils/errors.ts @@ -2,6 +2,8 @@ import {ErrorInfo} from 'react' import HoneyBadger from 'honeybadger-js' import {CLOUD, GIT_SHA} from 'src/shared/constants' +import {getUserFlags} from 'src/shared/utils/featureFlag' + if (CLOUD) { HoneyBadger.configure({ apiKey: process.env.HONEYBADGER_KEY, @@ -10,18 +12,44 @@ if (CLOUD) { }) } -interface AdditionalOptions { +// See https://docs.honeybadger.io/lib/javascript/guides/reporting-errors.html#additional-options +interface HoneyBadgerAdditionalOptions { component?: string context?: {[key: string]: any} + cookies?: {[key: string]: any} name?: string + params?: {[key: string]: any} } export const reportError = ( error: Error, - additionalOptions?: AdditionalOptions + additionalOptions?: HoneyBadgerAdditionalOptions ): void => { + let additionalContext = {} + if (additionalOptions && additionalOptions.context) { + additionalContext = {...additionalOptions.context} + } + + const context = { + ...additionalContext, + ...getUserFlags(), + } + + let options: HoneyBadgerAdditionalOptions = {} + if (additionalOptions) { + options = {...additionalOptions} + + delete options.context // already included in the above context object + } + if (CLOUD) { - HoneyBadger.notify(error, additionalOptions) + HoneyBadger.notify(error, {context, ...options}) + } else { + const honeyBadgerContext = (HoneyBadger as any).context + /* eslint-disable no-console */ + console.log('Context that would have been sent to HoneyBadger:') + console.table({...honeyBadgerContext, ...context, ...options}) + /* eslint-enable no-console */ } }