2016-08-31 15 views
5

Używam Electrons Quick Start Projekt (Commit dbef48ee7d072a38724ecfa57601e39d36e9714e) do testowania wyjątków.Czy możliwe jest wychwycenie wyjątków procesów renderujących w głównym procesie elektronów?

W index.html Zmieniłem nazwę wymaganego modułu od renderer.js do rendererXXX.js.

require('./renderer.js') 

co skutkuje oczekiwanym exeption (jest on widoczny w DevTools dla tego okna):

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

Teraz byłoby miło, jeśli główny proces (patrz main.js) ma świadomość, że jeden proces renderowania nie powiódł się. Tak więc owinął instatiation okna w try-catch bloku

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

Ale zdałem sobie sprawę, że wyjątek jest nie przekazane do głównego-procesu. Jakie są typowe sposoby obsługi wyjątków procesów renderowania - czy istnieje sposób na ich obsługę z głównego procesu?

EDIT:

ja owinięty również wiersz, który ładuje index.html do try-catch, ale nadal nie mogę obsłużyć błąd:

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

Spróbuj umieścić try-catch wewnątrz 'imprezy createWindow' funkcja obsługi. – Bergi

+0

@Bergi: To też nie zadziałało - nadal nie widzę wyjątku w głównym procesie. (Zobacz moje zaktualizowane pytanie) – Edward

Odpowiedz

8

okna Electron są świadczone w ich własnym procesie. Z tego powodu nie ma żadnej, jeśli w ogóle, komunikacji pomiędzy głównym procesem a procesami renderowania. Najlepsze, co możesz zrobić, to złapać błędy w procesie renderowania i użyć modułu IPC Electrons, aby przekazać je z powrotem do głównego procesu.

W swojej uczynienia procesu:

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

w głównym procesie:

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

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

Dodatkowo głównym proces można oglądać do ograniczonego zestawu zdarzeń bezpośrednio w oknie (lub w oknach webContents):

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

...

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

Czy istnieje powód do zawijania 'ipc.send' do' window.onerror() 'zamiast' try ... catch'? – Edward

+0

Cóż 'onerror' zadziała dla dowolnego błędu JS. Ale możesz "spróbować złapać" na czymś konkretnym w razie potrzeby. – Teak

+0

"window.on (" brak odpowiedzi "..." idzie do głównego? I czy istnieje sposób, aby dowiedzieć się, przez które okno wysłano wiadomość IPC? – Edward

3

Miałem podobny problem, gdy chciałem zalogować błędy do pliku z głównego procesu. Oto uzupełnienie odpowiedzi już dostarczonej przez Teak:

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

będzie działać. Należy pamiętać, że wywołanie zwrotne onerror przekazuje 5 argumentów, z których ostatni jest rzeczywistym obiektem błędu.

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

Jednakże, ponieważ wiadomości są szeregowane przy wysyłaniu przez IPC, to nie jest możliwe, aby przekazać obiekt Błąd w pełni, ponieważ nie będzie szeregować poprawnie domyślnie. Dlatego dane muszą być masowane przed wysłaniem, jeśli potrzebujesz więcej szczegółów błędu (takich jak ślad stosu itp.).

użyłem następujących Is it not possible to stringify an Error using JSON.stringify? dla niektórych pomysłów i końcowy wynik był następujący:

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)); 
} 

Następnie w 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); 
})