2016-08-31 22 views
5

我使用Electrons Quick Start Projekt(Commit dbef48ee7d072a38724ecfa57601e39d36e9714e)来测试异常。是否有可能在电子主流程中捕捉渲染器进程的异常?

index.html我将所需模块的名称从renderer.js更改为rendererXXX.js

require('./renderer.js') 

导致预期Exeption(它是在devtools该窗口可见):

Uncaught Error: Cannot find module './rendererXXX.js' 

现在,这将是很好,如果主过程(见main.js)知道,一个渲染器进程失败。因此,我包裹窗口instatiation成的try-catch块

try { 
    app.on('ready', createWindow) 
} catch (e) { 
    console.log("Exception caught: " + e.message); 
} finally { 
    // nothing yet 
} 

但是我意识到,有例外是不转发到主处理。那么处理渲染器进程异常的典型方法是什么?有没有办法从主进程处理它们?

编辑:

我还裹着一个加载index.html成的try-catch行了,但我仍然无法处理错误:

try { 
    // and load the index.html of the app. 
    mainWindow.loadURL(`file://${__dirname}/index.html`) 
    } catch (e) { 
    console.log("Exception caught in 'createWindow': " + e.message); 
    } 
+0

尝试把在try-catch的'createWindow'事件中处理函数。 – Bergi

+0

@Bergi:这也不起作用 - 我仍然无法在主进程中看到异常。 (查看我更新的问题) – Edward

回答

8

电子窗口在自己的进程呈现。因此,主进程和渲染进程之间几乎没有任何通信。您可以做的最好的方法是在渲染过程中捕捉错误,并使用Electrons IPC模块将它们传回给主流程。

在渲染过程:

var ipc = require('electron').ipcRenderer; 
window.onerror = function(error, url, line) { 
    ipc.send('errorInWindow', error); 
}; 

在你的主要过程:

var ipc = require('electron').ipcMain; 

ipc.on('errorInWindow', function(event, data){ 
    console.log(data) 
}); 

另外你的主要过程可以观看直接在窗口上一组有限的事件(或在窗户上webContents ):

window.on('unresponsive', function() { 
    console.log('window crashed'); 
}); 

...

window.webContents.on('did-fail-load', function() { 
    console.log('window failed load'); 
}); 
+0

是否有将'ipc.send'封装到'window.onerror()'而不是'try ... catch'的理由? – Edward

+0

那么'onerror'将适用于任何JS错误。但是如果需要的话,你可以尝试抓住某些特定的东西。 – Teak

+0

'window.on('无响应''...'进入主窗口吗?有没有办法找出IPC消息被发送到哪个窗口? – Edward

3

我有一个类似的问题,我想将错误记录到主进程的文件中。以下是柚木已经提供的答案:

var ipc = require('electron').ipcRenderer; 
window.onerror = function(error, url, line) { 
    ipc.send('errorInWindow', error); 
}; 

会起作用。请记住,onerror回调会传递5个参数,其中最后一个是实际的Error对象。

https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror

然而,由于消息通过IPC发送时是串行化的,它不可能完全传递错误的对象,因为它不会在默认情况下正确地序列。因此,如果需要更多错误细节(如堆栈跟踪等),则在发送数据之前需要对数据进行处理。

我用下面的Is it not possible to stringify an Error using JSON.stringify?的一些想法和最终的结果是:

var objFromError = function(err, filter, space) { 
    var plainObject = {}; 
    Object.getOwnPropertyNames(err).forEach(function(key) { 
    plainObject[key] = err[key]; 
    }); 

    return plainObject; 
}; 

window.onerror = function (msg, url, lineNo, columnNo, error) { 
    ipcRenderer.send('asynchronous-windowerr', 'main', objFromError(error)); 
} 

然后在main.js:

ipcMain.on('asynchronous-windowerr', function(event, source, err) { 
    var str = source + ': '; 

    if(err != null) { 
     if(err.stack != null) { 
      str += err.stack; 
     } else if(err.message != null) { 
      str += err.message; 
     } 
    } 

    loggerr.appendLogFile(errLogFile, 'err', str); 
})