const Raven = require('raven-js') const METAMASK_DEBUG = process.env.METAMASK_DEBUG const extractEthjsErrorMessage = require('./extractEthjsErrorMessage') const PROD = 'https://3567c198f8a8412082d32655da2961d0@sentry.io/273505' const DEV = 'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496' module.exports = setupRaven // Setup raven / sentry remote error reporting function setupRaven (opts) { const { releaseVersion } = opts let ravenTarget // detect brave const isBrave = Boolean(window.chrome.ipcRenderer) if (METAMASK_DEBUG) { console.log('Setting up Sentry Remote Error Reporting: DEV') ravenTarget = DEV } else { console.log('Setting up Sentry Remote Error Reporting: PROD') ravenTarget = PROD } const client = Raven.config(ravenTarget, { releaseVersion, transport: function (opts) { opts.data.extra.isBrave = isBrave const report = opts.data try { // handle error-like non-error exceptions rewriteErrorLikeExceptions(report) // simplify certain complex error messages (e.g. Ethjs) simplifyErrorMessages(report) // modify report urls rewriteReportUrls(report) } catch (err) { console.warn(err) } // make request normally client._makeRequest(opts) }, }) client.install() return Raven } function rewriteErrorLikeExceptions (report) { // handle errors that lost their error-ness in serialization (e.g. dnode) rewriteErrorMessages(report, (errorMessage) => { if (!errorMessage.includes('Non-Error exception captured with keys:')) return errorMessage if (!(report.extra && report.extra.__serialized__ && report.extra.__serialized__.message)) return errorMessage return `Non-Error Exception: ${report.extra.__serialized__.message}` }) } function simplifyErrorMessages (report) { rewriteErrorMessages(report, (errorMessage) => { // simplify ethjs error messages errorMessage = extractEthjsErrorMessage(errorMessage) // simplify 'Transaction Failed: known transaction' if (errorMessage.indexOf('Transaction Failed: known transaction') === 0) { // cut the hash from the error message errorMessage = 'Transaction Failed: known transaction' } return errorMessage }) } function rewriteErrorMessages (report, rewriteFn) { // rewrite top level message if (report.message) report.message = rewriteFn(report.message) // rewrite each exception message if (report.exception && report.exception.values) { report.exception.values.forEach(item => { item.value = rewriteFn(item.value) }) } } function rewriteReportUrls (report) { // update request url report.request.url = toMetamaskUrl(report.request.url) // update exception stack trace if (report.exception && report.exception.values) { report.exception.values.forEach(item => { item.stacktrace.frames.forEach(frame => { frame.filename = toMetamaskUrl(frame.filename) }) }) } } function toMetamaskUrl (origUrl) { const filePath = origUrl.split(location.origin)[1] if (!filePath) return origUrl const metamaskUrl = `metamask${filePath}` return metamaskUrl }