crash-reporter.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. 'use strict'
  2. const {spawn} = require('child_process')
  3. const os = require('os')
  4. const path = require('path')
  5. const electron = require('electron')
  6. const {app} = process.type === 'browser' ? electron : electron.remote
  7. const binding = process.atomBinding('crash_reporter')
  8. class CrashReporter {
  9. start (options) {
  10. if (options == null) {
  11. options = {}
  12. }
  13. this.productName = options.productName != null ? options.productName : app.getName()
  14. let {companyName, extra, ignoreSystemCrashHandler, submitURL, uploadToServer} = options
  15. if (uploadToServer == null) {
  16. // TODO: Remove deprecated autoSubmit property in 2.0
  17. uploadToServer = options.autoSubmit
  18. }
  19. if (uploadToServer == null) {
  20. uploadToServer = true
  21. }
  22. if (ignoreSystemCrashHandler == null) {
  23. ignoreSystemCrashHandler = false
  24. }
  25. if (extra == null) {
  26. extra = {}
  27. }
  28. if (extra._productName == null) {
  29. extra._productName = this.getProductName()
  30. }
  31. if (extra._companyName == null) {
  32. extra._companyName = companyName
  33. }
  34. if (extra._version == null) {
  35. extra._version = app.getVersion()
  36. }
  37. if (companyName == null) {
  38. throw new Error('companyName is a required option to crashReporter.start')
  39. }
  40. if (submitURL == null) {
  41. throw new Error('submitURL is a required option to crashReporter.start')
  42. }
  43. if (process.platform === 'win32') {
  44. const args = [
  45. '--reporter-url=' + submitURL,
  46. '--application-name=' + this.getProductName(),
  47. '--crashes-directory=' + this.getCrashesDirectory(),
  48. '--v=1'
  49. ]
  50. const env = {
  51. ELECTRON_INTERNAL_CRASH_SERVICE: 1
  52. }
  53. spawn(process.execPath, args, {
  54. env: env,
  55. detached: true
  56. })
  57. }
  58. binding.start(this.getProductName(), companyName, submitURL, this.getCrashesDirectory(), uploadToServer, ignoreSystemCrashHandler, extra)
  59. }
  60. getLastCrashReport () {
  61. const reports = this.getUploadedReports()
  62. if (reports.length > 0) {
  63. return reports[0]
  64. } else {
  65. return null
  66. }
  67. }
  68. getUploadedReports () {
  69. return binding._getUploadedReports(this.getCrashesDirectory())
  70. }
  71. getCrashesDirectory () {
  72. const crashesDir = this.getProductName() + ' Crashes'
  73. return path.join(this.getTempDirectory(), crashesDir)
  74. }
  75. getProductName () {
  76. if (this.productName == null) {
  77. this.productName = app.getName()
  78. }
  79. return this.productName
  80. }
  81. getTempDirectory () {
  82. if (this.tempDirectory == null) {
  83. try {
  84. this.tempDirectory = app.getPath('temp')
  85. } catch (error) {
  86. // app.getPath may throw so fallback to OS temp directory
  87. this.tempDirectory = os.tmpdir()
  88. }
  89. }
  90. return this.tempDirectory
  91. }
  92. getUploadToServer () {
  93. if (process.type === 'browser') {
  94. return binding._getUploadToServer()
  95. } else {
  96. throw new Error('getUploadToServer can only be called from the main process')
  97. }
  98. }
  99. setUploadToServer (uploadToServer) {
  100. if (process.type === 'browser') {
  101. return binding._setUploadToServer(uploadToServer)
  102. } else {
  103. throw new Error('setUploadToServer can only be called from the main process')
  104. }
  105. }
  106. }
  107. module.exports = new CrashReporter()