-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a crash reporter to diagnose CLI crashes. Update the service endp…
…oint URL. All crashes get submitted by default. The user has can turn off crash reporting if he wants to. Add lots of tests. Thanks a lot @rwaldron.
- Loading branch information
Showing
7 changed files
with
659 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// System Objects | ||
var os = require('os'); | ||
|
||
// Third Party Dependencies | ||
var request = require('request'); | ||
var tags = require('common-tags'); | ||
|
||
// Internal | ||
var logs = require('./logs'); | ||
var packageJson = require('../package.json'); | ||
var Preferences = require('./preferences'); | ||
|
||
// the value of the crash reporter preference | ||
// the value has to be one of 'on' or 'off' | ||
var CRASH_REPORTER_PREFERENCE = 'crash.reporter.preference'; | ||
var SUBMIT_CRASH_URL = 'http://crash-reporter.tessel.io/crashes/submit'; | ||
|
||
// override for testing | ||
if (process.env.DEV_MODE === 'true') { | ||
SUBMIT_CRASH_URL = 'http://localhost:8080/crashes/submit'; | ||
} | ||
|
||
var CrashReporter = {}; | ||
|
||
CrashReporter.off = function() { | ||
return Preferences.write(CRASH_REPORTER_PREFERENCE, 'off') | ||
.catch(error => { | ||
// do nothing | ||
// do not crash the crash reporter :) | ||
logs.err('Error turning off crash reporter preferences', error); | ||
}); | ||
}; | ||
|
||
CrashReporter.on = function() { | ||
return Preferences.write(CRASH_REPORTER_PREFERENCE, 'on') | ||
.catch(error => { | ||
// do nothing | ||
// do not crash the crash reporter :) | ||
logs.err('Error turning on crash reporter preferences', error); | ||
}); | ||
}; | ||
|
||
CrashReporter.submit = function(report) { | ||
return Preferences.read(CRASH_REPORTER_PREFERENCE, 'on') | ||
.then(value => { | ||
if (value === 'on') { | ||
var labels = tags.stripIndent ` | ||
${packageJson.name}, | ||
CLI version: ${packageJson.version}, | ||
Node version: ${process.version}, | ||
OS platform: ${os.platform()}, | ||
OS release: ${os.release()} | ||
`; | ||
|
||
CrashReporter.post(labels, report) | ||
.then(() => { | ||
logs.info('Done !'); | ||
}) | ||
.catch(error => { | ||
logs.err('Error submitting crash report', error); | ||
}); | ||
} | ||
}) | ||
.catch(error => { | ||
// do nothing | ||
// do not crash the crash reporter :) | ||
logs.err('Error submitting crash report', error); | ||
}); | ||
}; | ||
|
||
CrashReporter.post = function(labels, report) { | ||
return new Promise((resolve, reject) => { | ||
request.post({ | ||
url: SUBMIT_CRASH_URL, | ||
form: { | ||
crash: report, | ||
labels: labels, | ||
f: 'json' | ||
} | ||
}, (error, httpResponse, body) => { | ||
try { | ||
if (error) { | ||
reject(error); | ||
} else { | ||
var json = JSON.parse(body); | ||
if (json.error) { | ||
reject(json.error); | ||
} else { | ||
resolve(); | ||
} | ||
} | ||
} catch (exception) { | ||
reject(exception); | ||
} | ||
}); | ||
}); | ||
}; | ||
|
||
CrashReporter.test = () => { | ||
return Promise.reject(new Error('Testing the crash reporter')); | ||
}; | ||
|
||
var onError = error => { | ||
return CrashReporter.submit(error.stack); | ||
}; | ||
|
||
process.on('unhandledRejection', onError); | ||
process.on('uncaughtException', onError); | ||
|
||
module.exports = CrashReporter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// System Objects | ||
var path = require('path'); | ||
|
||
// Third Party Dependencies | ||
var fs = require('fs-extra'); | ||
|
||
// Internal | ||
var logs = require('./logs'); | ||
|
||
|
||
var home = (process.platform.startsWith('win')) ? process.env.HOMEPATH : process.env.HOME; | ||
var preferencesJson = path.join(home, '.tessel', 'preferences.json'); | ||
var Preferences = {}; | ||
|
||
Preferences.read = function(key, defaultValue) { | ||
return Preferences.load().then(contents => { | ||
if (contents) { | ||
return contents[key] || defaultValue; | ||
} else { | ||
return defaultValue; | ||
} | ||
}) | ||
.catch(error => { | ||
logs.err('Error reading preference', key, error); | ||
return defaultValue; | ||
}); | ||
}; | ||
|
||
Preferences.write = function(key, value) { | ||
return new Promise((resolve, reject) => { | ||
Preferences.load() | ||
.then(contents => { | ||
contents = contents || {}; | ||
contents[key] = value; | ||
fs.writeFile(preferencesJson, JSON.stringify(contents), function(error) { | ||
if (error) { | ||
logs.err('Error writing preference', key, value); | ||
reject(error); | ||
} else { | ||
resolve(); | ||
} | ||
}); | ||
}) | ||
.catch(error => { | ||
reject(error); | ||
}); | ||
}); | ||
}; | ||
|
||
Preferences.load = function() { | ||
return new Promise((resolve, reject) => { | ||
fs.exists(preferencesJson, (exists) => { | ||
if (exists) { | ||
fs.readFile(preferencesJson, (error, data) => { | ||
if (error) { | ||
reject(error); | ||
} else { | ||
resolve(JSON.parse(data)); | ||
} | ||
}); | ||
} else { | ||
// we don't have any local preferences | ||
// return falsy value | ||
resolve(); | ||
} | ||
}); | ||
}); | ||
}; | ||
|
||
module.exports = Preferences; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.