diff --git a/src/commands/testCrash.js b/src/commands/testCrash.js
index 0725988a..e5521c0c 100644
--- a/src/commands/testCrash.js
+++ b/src/commands/testCrash.js
@@ -2,16 +2,15 @@
// This is a test example for dev testing purpose.
-import { Observable } from 'rxjs'
import { createCommand, Command } from 'helpers/ipc'
type Input = void
type Result = void
-const cmd: Command = createCommand('testCrash', () =>
- Observable.create(() => {
- process.exit(1)
- }),
-)
+const cmd: Command = createCommand('testCrash', () => {
+ // $FlowFixMe
+ crashTest() // eslint-disable-line
+ throw new Error()
+})
export default cmd
diff --git a/src/components/modals/Debug.js b/src/components/modals/Debug.js
index bcd5284a..c87bbf9f 100644
--- a/src/components/modals/Debug.js
+++ b/src/components/modals/Debug.js
@@ -31,12 +31,16 @@ class Debug extends Component<*, *> {
)
}
- onCrash = () => {
+ onInternalCrash = () => {
testCrash.send().subscribe({
error: this.error,
})
}
+ onCrashHere = () => {
+ throw new Error('CrashTest')
+ }
+
onClickStressDevice = (device: *) => async () => {
try {
const currency = getCryptoCurrencyById('bitcoin')
@@ -142,8 +146,11 @@ class Debug extends Component<*, *> {
)}
-
diff --git a/src/helpers/anonymizer.js b/src/helpers/anonymizer.js
new file mode 100644
index 00000000..e9237fb2
--- /dev/null
+++ b/src/helpers/anonymizer.js
@@ -0,0 +1,16 @@
+// @flow
+
+export default {
+ url: (url: string): string =>
+ url
+ .replace(/\/addresses\/[^/]+/g, '/addresses/')
+ .replace(/blockHash=[^&]+/g, 'blockHash='),
+
+ appURI: (uri: string): string => uri.replace(/account\/[^/]/g, 'account/'),
+
+ filepath: (filepath: string): string => {
+ const i = filepath.indexOf('/node_modules')
+ if (i !== -1) return `.${filepath.slice(i)}`
+ return filepath
+ },
+}
diff --git a/src/logger.js b/src/logger.js
index e2f64c76..2b4956a2 100644
--- a/src/logger.js
+++ b/src/logger.js
@@ -3,6 +3,7 @@
import winston from 'winston'
import Transport from 'winston-transport'
import resolveLogsDirectory, { RotatingLogFileParameters } from 'helpers/resolveLogsDirectory'
+import anonymizer from 'helpers/anonymizer'
import {
DEBUG_NETWORK,
@@ -85,13 +86,6 @@ const logger = winston.createLogger({
transports,
})
-const anonymousMode = !__DEV__
-
-function anonymizeURL(url) {
- if (!anonymousMode) return url
- return url.replace(/\/addresses\/[^/]+/g, '/addresses/')
-}
-
const logCmds = !__DEV__ || DEBUG_COMMANDS
const logDb = !__DEV__ || DEBUG_DB
const logRedux = !__DEV__ || DEBUG_ACTION
@@ -165,7 +159,7 @@ export default {
},
network: ({ method, url }: { method: string, url: string }) => {
- const log = `➡📡 ${method} ${anonymizeURL(url)}`
+ const log = `➡📡 ${method} ${anonymizer.url(url)}`
if (logNetwork) {
logger.log('info', log, { type: 'network' })
}
@@ -182,7 +176,7 @@ export default {
status: number,
responseTime: number,
}) => {
- const log = `✔📡 HTTP ${status} ${method} ${anonymizeURL(
+ const log = `✔📡 HTTP ${status} ${method} ${anonymizer.url(
url,
)} – finished in ${responseTime.toFixed(0)}ms`
if (logNetwork) {
@@ -203,7 +197,7 @@ export default {
error: string,
responseTime: number,
}) => {
- const log = `✖📡 HTTP ${status} ${method} ${anonymizeURL(
+ const log = `✖📡 HTTP ${status} ${method} ${anonymizer.url(
url,
)} – ${error} – failed after ${responseTime.toFixed(0)}ms`
if (logNetwork) {
@@ -220,9 +214,9 @@ export default {
url: string,
responseTime: number,
}) => {
- const log = `✖📡 NETWORK DOWN – ${method} ${anonymizeURL(url)} – after ${responseTime.toFixed(
- 0,
- )}ms`
+ const log = `✖📡 NETWORK DOWN – ${method} ${anonymizer.url(
+ url,
+ )} – after ${responseTime.toFixed(0)}ms`
if (logNetwork) {
logger.log('info', log, { type: 'network-down' })
}
diff --git a/src/sentry/install.js b/src/sentry/install.js
index 95a505d7..a3651e86 100644
--- a/src/sentry/install.js
+++ b/src/sentry/install.js
@@ -1,4 +1,6 @@
// @flow
+import anonymizer from 'helpers/anonymizer'
+/* eslint-disable no-continue */
require('../env')
@@ -11,6 +13,60 @@ export default (Raven: any, shouldSendCallback: () => boolean, userId: string) =
tags: { git_commit: __GIT_REVISION__ },
environment: __DEV__ ? 'development' : 'production',
shouldSendCallback,
+ dataCallback: (data: mixed) => {
+ // We are mutating the data to anonymize everything.
+
+ if (typeof data !== 'object' || !data) return data
+
+ delete data.server_name // hides the user machine name
+ if (typeof data.request === 'object' && data.request) {
+ const { request } = data
+ if (typeof request.url === 'string') {
+ request.url = anonymizer.appURI(request.url)
+ }
+ }
+
+ if (data.breadcrumbs && typeof data.breadcrumbs === 'object') {
+ const { breadcrumbs } = data
+ if (Array.isArray(breadcrumbs.values)) {
+ const { values } = breadcrumbs
+ for (const b of values) {
+ if (!b || typeof b !== 'object') continue
+ if (b.category === 'xhr' && b.data && typeof b.data === 'object') {
+ const { data } = b
+ if (typeof data.url === 'string') {
+ data.url = anonymizer.url(data.url)
+ }
+ }
+ }
+ }
+ }
+
+ if (data.exception && typeof data.exception === 'object') {
+ const { exception } = data
+ if (Array.isArray(exception.values)) {
+ const { values } = exception
+ for (const value of values) {
+ if (value && typeof value === 'object') {
+ const { stacktrace } = value
+ if (stacktrace && typeof stacktrace === 'object') {
+ if (Array.isArray(stacktrace.frames)) {
+ const { frames } = stacktrace
+ for (const frame of frames) {
+ if (frame && typeof frame === 'object' && typeof frame.filename === 'string') {
+ frame.filename = anonymizer.filepath(frame.filename)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ console.log('Sentry=>', data) // eslint-disable-line
+ return data
+ },
})
const user = {
ip_address: null,