Merge pull request #836 from feross/dc/fixes
Telemetry: log version in errors
This commit is contained in:
@@ -78,8 +78,8 @@ function init () {
|
|||||||
// Report uncaught exceptions
|
// Report uncaught exceptions
|
||||||
process.on('uncaughtException', (err) => {
|
process.on('uncaughtException', (err) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
var errJSON = {message: err.message, stack: err.stack}
|
var error = {message: err.message, stack: err.stack}
|
||||||
windows.main.dispatch('uncaughtError', 'main', errJSON)
|
windows.main.dispatch('uncaughtError', 'main', error)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ function init (state) {
|
|||||||
|
|
||||||
if (config.IS_PRODUCTION) {
|
if (config.IS_PRODUCTION) {
|
||||||
postToServer()
|
postToServer()
|
||||||
// If the user keeps WebTorrent running for a long time, post every 24h
|
// If the user keeps WebTorrent running for a long time, post every 12h
|
||||||
setInterval(postToServer, 12 * 3600 * 1000)
|
setInterval(postToServer, 12 * 3600 * 1000)
|
||||||
} else {
|
} else {
|
||||||
// Development: telemetry used only for local debugging
|
// Development: telemetry used only for local debugging
|
||||||
@@ -45,6 +45,7 @@ function init (state) {
|
|||||||
function reset () {
|
function reset () {
|
||||||
telemetry.uncaughtErrors = []
|
telemetry.uncaughtErrors = []
|
||||||
telemetry.playAttempts = {
|
telemetry.playAttempts = {
|
||||||
|
minVersion: config.APP_VERSION,
|
||||||
total: 0,
|
total: 0,
|
||||||
success: 0,
|
success: 0,
|
||||||
timeout: 0,
|
timeout: 0,
|
||||||
@@ -118,29 +119,60 @@ function getApproxNumTorrents (state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// An uncaught error happened in the main process or in one of the windows
|
// An uncaught error happened in the main process or in one of the windows
|
||||||
function logUncaughtError (procName, err) {
|
function logUncaughtError (procName, e) {
|
||||||
// Not initialized yet? Ignore.
|
// Not initialized yet? Ignore.
|
||||||
// Hopefully uncaught errors immediately on startup are fixed in dev
|
// Hopefully uncaught errors immediately on startup are fixed in dev
|
||||||
if (!telemetry) return
|
if (!telemetry) return
|
||||||
|
|
||||||
var message, stack
|
var message
|
||||||
if (err instanceof Error) {
|
var stack = ''
|
||||||
message = err.message
|
if (e.message) {
|
||||||
// Remove the first part of each file path in the stack trace.
|
// err is either an Error or a plain object {message, stack}
|
||||||
// - Privacy: remove personal info like C:\Users\<full name>
|
message = e.message
|
||||||
// - Aggregation: this lets us find which stacktraces occur often
|
stack = e.stack
|
||||||
stack = err.stack.replace(/\(.*app.asar/g, '(...')
|
} else if (e.error) {
|
||||||
|
// Uncaught Javascript errors (window.onerror), err is an ErrorEvent
|
||||||
|
if (!e.error.message) {
|
||||||
|
message = 'Unexpected ErrorEvent.error: ' + Object.keys(e.error).join(' ')
|
||||||
|
} else {
|
||||||
|
message = e.error.message
|
||||||
|
stack = e.error.stack
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
message = String(err)
|
// Resource errors (captured element.onerror), err is an Event
|
||||||
stack = ''
|
if (!e.target) {
|
||||||
|
message = 'Unexpected unknown error'
|
||||||
|
} else if (!e.target.error) {
|
||||||
|
message = 'Unexpected resource loading error: ' + getElemString(e.target)
|
||||||
|
} else {
|
||||||
|
message = 'Resource error ' + getElemString(e.target) + ': ' + e.target.error.code
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove the first part of each file path in the stack trace.
|
||||||
|
// - Privacy: remove personal info like C:\Users\<full name>
|
||||||
|
// - Aggregation: this lets us find which stacktraces occur often
|
||||||
|
if (stack && typeof stack === 'string') stack = stack.replace(/\(.*app.asar/g, '(...')
|
||||||
|
else if (stack) stack = 'Unexpected stack: ' + stack
|
||||||
|
|
||||||
// We need to POST the telemetry object, make sure it stays < 100kb
|
// We need to POST the telemetry object, make sure it stays < 100kb
|
||||||
if (telemetry.uncaughtErrors.length > 20) return
|
if (telemetry.uncaughtErrors.length > 20) return
|
||||||
if (message.length > 1000) message = message.substring(0, 1000)
|
if (message.length > 1000) message = message.substring(0, 1000)
|
||||||
if (stack.length > 1000) stack = stack.substring(0, 1000)
|
if (stack.length > 1000) stack = stack.substring(0, 1000)
|
||||||
|
|
||||||
telemetry.uncaughtErrors.push({process: procName, message, stack})
|
// Log the app version *at the time of the error*
|
||||||
|
var version = config.APP_VERSION
|
||||||
|
|
||||||
|
telemetry.uncaughtErrors.push({process: procName, message, stack, version})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turns a DOM element into a string, eg "DIV.my-class.visible"
|
||||||
|
function getElemString (elem) {
|
||||||
|
var ret = elem.tagName
|
||||||
|
try {
|
||||||
|
ret += '.' + Array.from(elem.classList).join('.')
|
||||||
|
} catch (e) {}
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// The user pressed play. It either worked, timed out, or showed the
|
// The user pressed play. It either worked, timed out, or showed the
|
||||||
|
|||||||
@@ -116,7 +116,8 @@ function onState (err, _state) {
|
|||||||
|
|
||||||
// Log uncaught JS errors
|
// Log uncaught JS errors
|
||||||
window.addEventListener('error',
|
window.addEventListener('error',
|
||||||
(e) => telemetry.logUncaughtError('window', e.error || e.target), true)
|
(e) => telemetry.logUncaughtError('window', e),
|
||||||
|
true /* capture */)
|
||||||
|
|
||||||
// Done! Ideally we want to get here < 500ms after the user clicks the app
|
// Done! Ideally we want to get here < 500ms after the user clicks the app
|
||||||
sound.play('STARTUP')
|
sound.play('STARTUP')
|
||||||
|
|||||||
Reference in New Issue
Block a user