From 5afa549b7003bcc41e5953023fecc715d204bd9c Mon Sep 17 00:00:00 2001 From: Evan Morikawa Date: Mon, 16 May 2016 11:31:08 -0700 Subject: [PATCH] fix(error): send all renderer errors to the browser process --- src/browser/application.es6 | 8 ++++++++ src/error-logger.js | 26 +++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/browser/application.es6 b/src/browser/application.es6 index 61e794a43..2704c97d3 100644 --- a/src/browser/application.es6 +++ b/src/browser/application.es6 @@ -546,6 +546,14 @@ export default class Application extends EventEmitter { sourceWindow.webContents.send('remote-run-results', params); delete this._sourceWindows[params.taskId]; }); + + ipcMain.on("report-error", (event, params = {}) => { + const errorParams = JSON.parse(params.errorJSON || ""); + let err = new Error(); + err = Object.assign(err, errorParams); + global.errorLogger.reportError(err, params.extra) + event.returnValue = true + }) } // Public: Executes the given command. diff --git a/src/error-logger.js b/src/error-logger.js index 8cf8c4fa5..86f1f3161 100644 --- a/src/error-logger.js +++ b/src/error-logger.js @@ -6,7 +6,9 @@ var ErrorLogger, _, fs, path, app, os, remote; os = require('os'); fs = require('fs-plus'); path = require('path'); +ipcRenderer = null; if (process.type === 'renderer') { + ipcRenderer = require('electron').ipcRenderer; remote = require('electron').remote; app = remote.app; } else { @@ -54,12 +56,30 @@ module.exports = ErrorLogger = (function() { ///////////////////////////////////////////////////////////////////// ErrorLogger.prototype.reportError = function(error, extra) { - var nslog = require('nslog'); if (!error) { error = {stack: ""} } this._appendLog(error.stack) if (extra) { this._appendLog(extra) } - this._notifyExtensions("reportError", error, extra) - if (process.type === 'browser') { nslog(error.stack) } + if (process.type === "renderer") { + var errorJSON = JSON.stringify(error); + + /** + * We synchronously send all errors to the backend main process. + * + * This is important because errors can frequently happen right + * before a renderer window is closing. Since error reporting hits + * APIs and is asynchronous it's possible for the window to be + * destroyed before the report makes it. + * + * This is a rare use of `sendSync` to ensure the command has made + * it before the window closes. + */ + ipcRenderer.sendSync("report-error", {errorJSON: errorJSON, extra: extra}) + + } else { + var nslog = require('nslog'); + this._notifyExtensions("reportError", error, extra) + nslog(error.stack) + } } ErrorLogger.prototype.openLogs = function() {