mirror of
https://github.com/finos/SymphonyElectron.git
synced 2025-02-25 18:55:29 -06:00
Electron-401 (fixes crash reporter) (#334)
- fix crash reporter - fix typo - Add support to generate crash report - Add logic to store globally and return - PR review fixes - Add logic to validate file mime type
This commit is contained in:
parent
2de86c8003
commit
3be2986c7e
@ -7,6 +7,7 @@ const fs = require('fs');
|
|||||||
const log = require('../log.js');
|
const log = require('../log.js');
|
||||||
const logLevels = require('../enums/logLevels.js');
|
const logLevels = require('../enums/logLevels.js');
|
||||||
const buildNumber = require('../../package.json').buildNumber;
|
const buildNumber = require('../../package.json').buildNumber;
|
||||||
|
const { initCrashReporterMain, initCrashReporterRenderer } = require('../crashReporter.js');
|
||||||
|
|
||||||
let aboutWindow;
|
let aboutWindow;
|
||||||
|
|
||||||
@ -80,9 +81,27 @@ function openAboutWindow(windowName) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
aboutWindow.webContents.on('did-finish-load', () => {
|
aboutWindow.webContents.on('did-finish-load', () => {
|
||||||
|
// initialize crash reporter
|
||||||
|
initCrashReporterMain({ process: 'about app window' });
|
||||||
|
initCrashReporterRenderer(aboutWindow, { process: 'render | about app window' });
|
||||||
aboutWindow.webContents.send('buildNumber', buildNumber || '0');
|
aboutWindow.webContents.send('buildNumber', buildNumber || '0');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
aboutWindow.webContents.on('crashed', function () {
|
||||||
|
const options = {
|
||||||
|
type: 'error',
|
||||||
|
title: 'Renderer Process Crashed',
|
||||||
|
message: 'Oops! Looks like we have had a crash.',
|
||||||
|
buttons: ['Close']
|
||||||
|
};
|
||||||
|
|
||||||
|
electron.dialog.showMessageBox(options, function () {
|
||||||
|
if (aboutWindow && !aboutWindow.isDestroyed()) {
|
||||||
|
aboutWindow.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
aboutWindow.on('close', () => {
|
aboutWindow.on('close', () => {
|
||||||
destroyWindow();
|
destroyWindow();
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const { remote, ipcRenderer } = require('electron');
|
const { remote, ipcRenderer, crashReporter } = require('electron');
|
||||||
|
|
||||||
renderDom();
|
renderDom();
|
||||||
|
|
||||||
@ -24,4 +24,10 @@ ipcRenderer.on('buildNumber', (event, buildNumber) => {
|
|||||||
if (versionText) {
|
if (versionText) {
|
||||||
versionText.innerHTML = version ? `Version ${version} (${version}.${buildNumber})` : 'N/A';
|
versionText.innerHTML = version ? `Version ${version} (${version}.${buildNumber})` : 'N/A';
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcRenderer.on('register-crash-reporter', (event, arg) => {
|
||||||
|
if (arg && typeof arg === 'object') {
|
||||||
|
crashReporter.start(arg);
|
||||||
|
}
|
||||||
});
|
});
|
@ -8,6 +8,7 @@ const fs = require('fs');
|
|||||||
const log = require('../log.js');
|
const log = require('../log.js');
|
||||||
const logLevels = require('../enums/logLevels.js');
|
const logLevels = require('../enums/logLevels.js');
|
||||||
const { isMac } = require('../utils/misc');
|
const { isMac } = require('../utils/misc');
|
||||||
|
const { initCrashReporterMain, initCrashReporterRenderer } = require('../crashReporter.js');
|
||||||
|
|
||||||
let basicAuthWindow;
|
let basicAuthWindow;
|
||||||
|
|
||||||
@ -95,10 +96,26 @@ function openBasicAuthWindow(windowName, hostname, isValidCredentials, clearSett
|
|||||||
});
|
});
|
||||||
|
|
||||||
basicAuthWindow.webContents.on('did-finish-load', () => {
|
basicAuthWindow.webContents.on('did-finish-load', () => {
|
||||||
|
// initialize crash reporter
|
||||||
|
initCrashReporterMain({ process: 'basic auth window' });
|
||||||
|
initCrashReporterRenderer(basicAuthWindow, { process: 'render | basic auth window' });
|
||||||
basicAuthWindow.webContents.send('hostname', hostname);
|
basicAuthWindow.webContents.send('hostname', hostname);
|
||||||
basicAuthWindow.webContents.send('isValidCredentials', isValidCredentials);
|
basicAuthWindow.webContents.send('isValidCredentials', isValidCredentials);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
basicAuthWindow.webContents.on('crashed', function () {
|
||||||
|
const options = {
|
||||||
|
type: 'error',
|
||||||
|
title: 'Renderer Process Crashed',
|
||||||
|
message: 'Oops! Looks like we have had a crash.',
|
||||||
|
buttons: ['Close']
|
||||||
|
};
|
||||||
|
|
||||||
|
electron.dialog.showMessageBox(options, function () {
|
||||||
|
closeAuthWindow(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
basicAuthWindow.on('close', () => {
|
basicAuthWindow.on('close', () => {
|
||||||
destroyWindow();
|
destroyWindow();
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const electron = require('electron');
|
const { ipcRenderer, crashReporter } = require('electron');
|
||||||
const ipc = electron.ipcRenderer;
|
|
||||||
|
|
||||||
renderDom();
|
renderDom();
|
||||||
|
|
||||||
@ -26,7 +25,7 @@ function loadContent() {
|
|||||||
|
|
||||||
if (cancel) {
|
if (cancel) {
|
||||||
cancel.addEventListener('click', () => {
|
cancel.addEventListener('click', () => {
|
||||||
ipc.send('close-basic-auth');
|
ipcRenderer.send('close-basic-auth');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,14 +38,14 @@ function submitForm() {
|
|||||||
let password = document.getElementById('password').value;
|
let password = document.getElementById('password').value;
|
||||||
|
|
||||||
if (username && password) {
|
if (username && password) {
|
||||||
ipc.send('login', { username, password });
|
ipcRenderer.send('login', { username, password });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the hosts name
|
* Updates the hosts name
|
||||||
*/
|
*/
|
||||||
ipc.on('hostname', (event, host) => {
|
ipcRenderer.on('hostname', (event, host) => {
|
||||||
let hostname = document.getElementById('hostname');
|
let hostname = document.getElementById('hostname');
|
||||||
|
|
||||||
if (hostname){
|
if (hostname){
|
||||||
@ -57,10 +56,16 @@ ipc.on('hostname', (event, host) => {
|
|||||||
/**
|
/**
|
||||||
* Triggered if user credentials are invalid
|
* Triggered if user credentials are invalid
|
||||||
*/
|
*/
|
||||||
ipc.on('isValidCredentials', (event, isValidCredentials) => {
|
ipcRenderer.on('isValidCredentials', (event, isValidCredentials) => {
|
||||||
let credentialsError = document.getElementById('credentialsError');
|
let credentialsError = document.getElementById('credentialsError');
|
||||||
|
|
||||||
if (credentialsError){
|
if (credentialsError){
|
||||||
credentialsError.style.display = isValidCredentials ? 'none' : 'block'
|
credentialsError.style.display = isValidCredentials ? 'none' : 'block'
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcRenderer.on('register-crash-reporter', (event, arg) => {
|
||||||
|
if (arg && typeof arg === 'object') {
|
||||||
|
crashReporter.start(arg);
|
||||||
|
}
|
||||||
});
|
});
|
85
js/crashReporter.js
Normal file
85
js/crashReporter.js
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
const { crashReporter } = require('electron');
|
||||||
|
const { getMultipleConfigField } = require('./config.js');
|
||||||
|
|
||||||
|
const log = require('./log.js');
|
||||||
|
const logLevels = require('./enums/logLevels.js');
|
||||||
|
|
||||||
|
const configFields = ['url', 'crashReporter'];
|
||||||
|
let crashReporterData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that returns all the required field for crash reporter
|
||||||
|
*
|
||||||
|
* @param extras {object}
|
||||||
|
* @return {Promise<any>}
|
||||||
|
*/
|
||||||
|
function getCrashReporterConfig(extras) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
|
if (crashReporterData && crashReporterData.companyName) {
|
||||||
|
crashReporterData.extra = Object.assign(crashReporterData.extra, extras);
|
||||||
|
resolve(crashReporterData);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getMultipleConfigField(configFields)
|
||||||
|
.then((data) => {
|
||||||
|
|
||||||
|
if (!data && !data.crashReporter && !data.crashReporter.companyName) {
|
||||||
|
reject('Company name cannot be empty');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
crashReporterData = {
|
||||||
|
companyName: data.crashReporter.companyName,
|
||||||
|
submitURL: data.crashReporter.submitURL,
|
||||||
|
uploadToServer: data.crashReporter.uploadToServer,
|
||||||
|
extra: Object.assign(
|
||||||
|
{podUrl: data.url},
|
||||||
|
extras
|
||||||
|
)
|
||||||
|
};
|
||||||
|
resolve(crashReporterData);
|
||||||
|
})
|
||||||
|
.catch((err) => log.send(
|
||||||
|
logLevels.ERROR,
|
||||||
|
'Unable to initialize crash reporter failed to read config file. Error is -> ' + err
|
||||||
|
));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function initCrashReporterMain(extras) {
|
||||||
|
getCrashReporterConfig(extras).then((mainCrashReporterData) => {
|
||||||
|
try {
|
||||||
|
crashReporter.start(mainCrashReporterData);
|
||||||
|
} catch (err) {
|
||||||
|
log.send(logLevels.ERROR, 'Failed to start crash reporter main process. Error is -> ' + err);
|
||||||
|
}
|
||||||
|
}).catch((err) => log.send(
|
||||||
|
logLevels.ERROR,
|
||||||
|
'Unable to initialize crash reporter for main process. Error is -> ' + err
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to initialize crash reporter for renderer process
|
||||||
|
*
|
||||||
|
* @param browserWindow {Electron.BrowserWindow}
|
||||||
|
* @param extras {Object}
|
||||||
|
*/
|
||||||
|
function initCrashReporterRenderer(browserWindow, extras) {
|
||||||
|
if (browserWindow && browserWindow.webContents && !browserWindow.isDestroyed()) {
|
||||||
|
getCrashReporterConfig(extras).then((rendererCrashReporterData) => {
|
||||||
|
browserWindow.webContents.send('register-crash-reporter', rendererCrashReporterData);
|
||||||
|
}).catch((err) => log.send(
|
||||||
|
logLevels.ERROR,
|
||||||
|
'Unable to initialize crash reporter for renderer process. Error is -> ' + err
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
initCrashReporterMain,
|
||||||
|
initCrashReporterRenderer,
|
||||||
|
};
|
@ -8,6 +8,7 @@ const fs = require('fs');
|
|||||||
const log = require('../log.js');
|
const log = require('../log.js');
|
||||||
const logLevels = require('../enums/logLevels.js');
|
const logLevels = require('../enums/logLevels.js');
|
||||||
const { isMac, isWindowsOS } = require('./../utils/misc.js');
|
const { isMac, isWindowsOS } = require('./../utils/misc.js');
|
||||||
|
const { initCrashReporterMain, initCrashReporterRenderer } = require('../crashReporter.js');
|
||||||
|
|
||||||
let screenPickerWindow;
|
let screenPickerWindow;
|
||||||
let preloadWindow;
|
let preloadWindow;
|
||||||
@ -91,9 +92,27 @@ function openScreenPickerWindow(eventSender, sources, id) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
screenPickerWindow.webContents.on('did-finish-load', () => {
|
screenPickerWindow.webContents.on('did-finish-load', () => {
|
||||||
|
// initialize crash reporter
|
||||||
|
initCrashReporterMain({ process: 'desktop capture window' });
|
||||||
|
initCrashReporterRenderer(screenPickerWindow, { process: 'render | desktop capture window' });
|
||||||
screenPickerWindow.webContents.send('desktop-capturer-sources', sources, isWindowsOS);
|
screenPickerWindow.webContents.send('desktop-capturer-sources', sources, isWindowsOS);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
screenPickerWindow.webContents.on('crashed', function () {
|
||||||
|
const options = {
|
||||||
|
type: 'error',
|
||||||
|
title: 'Renderer Process Crashed',
|
||||||
|
message: 'Oops! Looks like we have had a crash.',
|
||||||
|
buttons: ['Close']
|
||||||
|
};
|
||||||
|
|
||||||
|
electron.dialog.showMessageBox(options, function () {
|
||||||
|
if (screenPickerWindow && !screenPickerWindow.isDestroyed()) {
|
||||||
|
screenPickerWindow.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
screenPickerWindow.on('close', () => {
|
screenPickerWindow.on('close', () => {
|
||||||
destroyWindow();
|
destroyWindow();
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const { ipcRenderer } = require('electron');
|
const { ipcRenderer, crashReporter } = require('electron');
|
||||||
|
|
||||||
const screenRegExp = new RegExp(/^Screen \d+$/gmi);
|
const screenRegExp = new RegExp(/^Screen \d+$/gmi);
|
||||||
|
|
||||||
@ -265,4 +265,10 @@ function updateSelectedSource(index) {
|
|||||||
function closeScreenPickerWindow() {
|
function closeScreenPickerWindow() {
|
||||||
document.removeEventListener('keyUp', handleKeyUpPress.bind(this), true);
|
document.removeEventListener('keyUp', handleKeyUpPress.bind(this), true);
|
||||||
ipcRenderer.send('close-screen-picker');
|
ipcRenderer.send('close-screen-picker');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ipcRenderer.on('register-crash-reporter', (event, arg) => {
|
||||||
|
if (arg && typeof arg === 'object') {
|
||||||
|
crashReporter.start(arg);
|
||||||
|
}
|
||||||
|
});
|
@ -129,7 +129,8 @@ const template = [{
|
|||||||
{
|
{
|
||||||
label: isMac ? 'Show Logs in Finder' : 'Show Logs in Explorer',
|
label: isMac ? 'Show Logs in Finder' : 'Show Logs in Explorer',
|
||||||
click() {
|
click() {
|
||||||
|
|
||||||
|
const FILE_EXTENSIONS = [ '.log' ];
|
||||||
const MAC_LOGS_PATH = '/Library/Logs/Symphony/';
|
const MAC_LOGS_PATH = '/Library/Logs/Symphony/';
|
||||||
const WINDOWS_LOGS_PATH = '\\AppData\\Roaming\\Symphony\\';
|
const WINDOWS_LOGS_PATH = '\\AppData\\Roaming\\Symphony\\';
|
||||||
|
|
||||||
@ -146,7 +147,7 @@ const template = [{
|
|||||||
|
|
||||||
let destination = electron.app.getPath('downloads') + destPath + timestamp + '.zip';
|
let destination = electron.app.getPath('downloads') + destPath + timestamp + '.zip';
|
||||||
|
|
||||||
archiveHandler.generateArchiveForDirectory(source, destination)
|
archiveHandler.generateArchiveForDirectory(source, destination, FILE_EXTENSIONS)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
electron.shell.showItemInFolder(destination);
|
electron.shell.showItemInFolder(destination);
|
||||||
})
|
})
|
||||||
@ -157,10 +158,29 @@ const template = [{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Open Crashes Directory',
|
label: isMac ? 'Show crash dump in Finder' : 'Show crash dump in Explorer',
|
||||||
click() {
|
click() {
|
||||||
const crashesDirectory = electron.crashReporter.getCrashesDirectory() + '/completed';
|
const FILE_EXTENSIONS = isMac ? [ '.dmp' ] : [ '.dmp', '.txt' ];
|
||||||
electron.shell.showItemInFolder(crashesDirectory);
|
const crashesDirectory = electron.crashReporter.getCrashesDirectory();
|
||||||
|
let source = isMac ? crashesDirectory + '/completed' : crashesDirectory;
|
||||||
|
|
||||||
|
if (!fs.existsSync(source) || fs.readdirSync(source).length === 0) {
|
||||||
|
electron.dialog.showErrorBox('Failed!', 'No crashes available to share');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let destPath = isMac ? '/crashes_symphony_' : '\\crashes_symphony_';
|
||||||
|
let timestamp = new Date().getTime();
|
||||||
|
|
||||||
|
let destination = electron.app.getPath('downloads') + destPath + timestamp + '.zip';
|
||||||
|
|
||||||
|
archiveHandler.generateArchiveForDirectory(source, destination, FILE_EXTENSIONS)
|
||||||
|
.then(() => {
|
||||||
|
electron.shell.showItemInFolder(destination);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
electron.dialog.showErrorBox('Failed!', 'Unable to generate crash report due to -> ' + err);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -130,19 +130,6 @@ function createAPI() {
|
|||||||
*/
|
*/
|
||||||
ScreenSnippet: remote.require('./screenSnippet/index.js').ScreenSnippet,
|
ScreenSnippet: remote.require('./screenSnippet/index.js').ScreenSnippet,
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides API to crash the renderer process that calls this function
|
|
||||||
* Is only used for demos.
|
|
||||||
*/
|
|
||||||
crashRendererProcess: function () {
|
|
||||||
// For practical purposes, we don't allow
|
|
||||||
// this method to work in non-dev environments
|
|
||||||
if (!process.env.ELECTRON_DEV) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
process.crash();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides api for client side searching
|
* Provides api for client side searching
|
||||||
* using the SymphonySearchEngine library
|
* using the SymphonySearchEngine library
|
||||||
@ -394,9 +381,13 @@ function createAPI() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* an event triggered by the main process to start crash reporter
|
||||||
|
* in the render thread
|
||||||
|
*/
|
||||||
local.ipcRenderer.on('register-crash-reporter', (event, arg) => {
|
local.ipcRenderer.on('register-crash-reporter', (event, arg) => {
|
||||||
if (arg) {
|
if (arg && typeof arg === 'object') {
|
||||||
crashReporter.start({companyName: arg.companyName, submitURL: arg.submitURL, uploadToServer: arg.uploadToServer, extra: {'process': arg.process, podUrl: arg.podUrl}});
|
crashReporter.start(arg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3,11 +3,25 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const archiver = require('archiver');
|
const archiver = require('archiver');
|
||||||
|
const log = require('../log.js');
|
||||||
|
const logLevels = require('../enums/logLevels.js');
|
||||||
|
const mmm = require('mmmagic');
|
||||||
|
const Magic = mmm.Magic;
|
||||||
|
const magic = new Magic(mmm.MAGIC_MIME_TYPE);
|
||||||
|
|
||||||
function generateArchiveForDirectory(source, destination) {
|
/**
|
||||||
|
* Archives files in the source directory
|
||||||
|
* that matches the given file extension
|
||||||
|
*
|
||||||
|
* @param source {String} source path
|
||||||
|
* @param destination {String} destination path
|
||||||
|
* @param fileExtensions {Array} array of file ext
|
||||||
|
* @return {Promise<any>}
|
||||||
|
*/
|
||||||
|
function generateArchiveForDirectory(source, destination, fileExtensions) {
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
let output = fs.createWriteStream(destination);
|
let output = fs.createWriteStream(destination);
|
||||||
let archive = archiver('zip', {zlib: {level: 9}});
|
let archive = archiver('zip', {zlib: {level: 9}});
|
||||||
|
|
||||||
@ -20,20 +34,55 @@ function generateArchiveForDirectory(source, destination) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
archive.pipe(output);
|
archive.pipe(output);
|
||||||
|
|
||||||
let files = fs.readdirSync(source);
|
let files = fs.readdirSync(source);
|
||||||
files.forEach((file) => {
|
|
||||||
if (path.extname(file) === '.log') {
|
let filtered = files.filter((file) => fileExtensions.indexOf(path.extname(file)) !== -1);
|
||||||
archive.file(source + '/' + file, { name: 'logs/' + file });
|
mapMimeType(filtered, source)
|
||||||
}
|
.then((mappedData) => {
|
||||||
});
|
if (mappedData.length > 0) {
|
||||||
|
mappedData.map((data) => {
|
||||||
archive.finalize();
|
switch (data.mimeType) {
|
||||||
|
case 'text/plain':
|
||||||
|
if (path.extname(data.file) === '.txt') {
|
||||||
|
archive.file(source + '/' + data.file, { name: 'crashes/' + data.file });
|
||||||
|
} else {
|
||||||
|
archive.file(source + '/' + data.file, { name: 'logs/' + data.file });
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'application/x-dmp':
|
||||||
|
archive.file(source + '/' + data.file, { name: 'crashes/' + data.file });
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
archive.finalize();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
log.send(logLevels.ERROR, 'Failed to find mime type. Error is -> ' + err);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mapMimeType(files, source) {
|
||||||
|
return Promise.all(files.map((file) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
return magic.detectFile(source + '/' + file, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
return reject(err);
|
||||||
|
}
|
||||||
|
return resolve({file: file, mimeType: result});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}))
|
||||||
|
.then((data) => data)
|
||||||
|
.catch((err) => log.send(logLevels.ERROR, 'Failed to find mime type. Error is -> ' + err));
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
generateArchiveForDirectory: generateArchiveForDirectory
|
generateArchiveForDirectory: generateArchiveForDirectory
|
||||||
};
|
};
|
@ -4,7 +4,6 @@ const fs = require('fs');
|
|||||||
const electron = require('electron');
|
const electron = require('electron');
|
||||||
const app = electron.app;
|
const app = electron.app;
|
||||||
const globalShortcut = electron.globalShortcut;
|
const globalShortcut = electron.globalShortcut;
|
||||||
const crashReporter = electron.crashReporter;
|
|
||||||
const BrowserWindow = electron.BrowserWindow;
|
const BrowserWindow = electron.BrowserWindow;
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const nodeURL = require('url');
|
const nodeURL = require('url');
|
||||||
@ -24,6 +23,7 @@ const { getConfigField, updateConfigField, getGlobalConfigField } = require('./c
|
|||||||
const { isMac, isNodeEnv, isWindows10, isWindowsOS } = require('./utils/misc');
|
const { isMac, isNodeEnv, isWindows10, isWindowsOS } = require('./utils/misc');
|
||||||
const { deleteIndexFolder } = require('./search/search.js');
|
const { deleteIndexFolder } = require('./search/search.js');
|
||||||
const { isWhitelisted } = require('./utils/whitelistHandler');
|
const { isWhitelisted } = require('./utils/whitelistHandler');
|
||||||
|
const { initCrashReporterMain, initCrashReporterRenderer } = require('./crashReporter.js');
|
||||||
|
|
||||||
// show dialog when certificate errors occur
|
// show dialog when certificate errors occur
|
||||||
require('./dialogs/showCertError.js');
|
require('./dialogs/showCertError.js');
|
||||||
@ -188,6 +188,10 @@ function doCreateMainWindow(initialUrl, initialBounds, isCustomTitleBar) {
|
|||||||
// content can be cached and will still finish load but
|
// content can be cached and will still finish load but
|
||||||
// we might not have network connectivity, so warn the user.
|
// we might not have network connectivity, so warn the user.
|
||||||
mainWindow.webContents.on('did-finish-load', function () {
|
mainWindow.webContents.on('did-finish-load', function () {
|
||||||
|
// Initialize crash reporter
|
||||||
|
initCrashReporterMain({ process: 'main window' });
|
||||||
|
initCrashReporterRenderer(mainWindow, { process: 'render | main window' });
|
||||||
|
|
||||||
url = mainWindow.webContents.getURL();
|
url = mainWindow.webContents.getURL();
|
||||||
if (isCustomTitleBarEnabled) {
|
if (isCustomTitleBarEnabled) {
|
||||||
mainWindow.webContents.insertCSS(fs.readFileSync(path.join(__dirname, '/windowsTitleBar/style.css'), 'utf8').toString());
|
mainWindow.webContents.insertCSS(fs.readFileSync(path.join(__dirname, '/windowsTitleBar/style.css'), 'utf8').toString());
|
||||||
@ -318,23 +322,6 @@ function doCreateMainWindow(initialUrl, initialBounds, isCustomTitleBar) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
getConfigField('url')
|
|
||||||
.then(initializeCrashReporter)
|
|
||||||
.catch(app.quit);
|
|
||||||
|
|
||||||
function initializeCrashReporter(podUrl) {
|
|
||||||
getConfigField('crashReporter')
|
|
||||||
.then((crashReporterConfig) => {
|
|
||||||
log.send(logLevels.INFO, 'Initializing crash reporter on the main window!');
|
|
||||||
crashReporter.start({ companyName: crashReporterConfig.companyName, submitURL: crashReporterConfig.submitURL, uploadToServer: crashReporterConfig.uploadToServer, extra: { 'process': 'renderer / main window', podUrl: podUrl } });
|
|
||||||
log.send(logLevels.INFO, 'initialized crash reporter on the main window!');
|
|
||||||
mainWindow.webContents.send('register-crash-reporter', { companyName: crashReporterConfig.companyName, submitURL: crashReporterConfig.submitURL, uploadToServer: crashReporterConfig.uploadToServer, process: 'preload script / main window renderer' });
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
log.send(logLevels.ERROR, 'Unable to initialize crash reporter in the main window. Error is -> ' + err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// open external links in default browser - a tag with href='_blank' or window.open
|
// open external links in default browser - a tag with href='_blank' or window.open
|
||||||
mainWindow.webContents.on('new-window', handleNewWindow);
|
mainWindow.webContents.on('new-window', handleNewWindow);
|
||||||
|
|
||||||
@ -420,19 +407,8 @@ function doCreateMainWindow(initialUrl, initialBounds, isCustomTitleBar) {
|
|||||||
browserWin.setMenu(null);
|
browserWin.setMenu(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
getConfigField('url')
|
initCrashReporterMain({ process: 'pop-out window' });
|
||||||
.then((podUrl) => {
|
initCrashReporterRenderer(browserWin, { process: 'render | pop-out window' });
|
||||||
getConfigField('crashReporter')
|
|
||||||
.then((crashReporterConfig) => {
|
|
||||||
crashReporter.start({ companyName: crashReporterConfig.companyName, submitURL: crashReporterConfig.submitURL, uploadToServer: crashReporterConfig.uploadToServer, extra: { 'process': 'renderer / child window', podUrl: podUrl } });
|
|
||||||
log.send(logLevels.INFO, 'initialized crash reporter on a child window!');
|
|
||||||
browserWin.webContents.send('register-crash-reporter', { companyName: crashReporterConfig.companyName, submitURL: crashReporterConfig.submitURL, uploadToServer: crashReporterConfig.uploadToServer, process: 'preload script / child window renderer' });
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
log.send(logLevels.ERROR, 'Unable to initialize crash reporter in the child window. Error is -> ' + err);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(app.quit);
|
|
||||||
|
|
||||||
browserWin.winName = frameName;
|
browserWin.winName = frameName;
|
||||||
browserWin.setAlwaysOnTop(alwaysOnTop);
|
browserWin.setAlwaysOnTop(alwaysOnTop);
|
||||||
@ -452,7 +428,7 @@ function doCreateMainWindow(initialUrl, initialBounds, isCustomTitleBar) {
|
|||||||
browserWin.webContents.removeListener('crashed', handleChildWindowCrashEvent);
|
browserWin.webContents.removeListener('crashed', handleChildWindowCrashEvent);
|
||||||
});
|
});
|
||||||
|
|
||||||
let handleChildWindowCrashEvent = () => {
|
let handleChildWindowCrashEvent = (e) => {
|
||||||
const options = {
|
const options = {
|
||||||
type: 'error',
|
type: 'error',
|
||||||
title: 'Renderer Process Crashed',
|
title: 'Renderer Process Crashed',
|
||||||
@ -460,14 +436,16 @@ function doCreateMainWindow(initialUrl, initialBounds, isCustomTitleBar) {
|
|||||||
buttons: ['Reload', 'Close']
|
buttons: ['Reload', 'Close']
|
||||||
};
|
};
|
||||||
|
|
||||||
electron.dialog.showMessageBox(options, function (index) {
|
let childBrowserWindow = BrowserWindow.fromWebContents(e.sender);
|
||||||
if (index === 0) {
|
if (childBrowserWindow && !childBrowserWindow.isDestroyed()) {
|
||||||
browserWin.reload();
|
electron.dialog.showMessageBox(childBrowserWindow, options, function (index) {
|
||||||
}
|
if (index === 0) {
|
||||||
else {
|
childBrowserWindow.reload();
|
||||||
browserWin.close();
|
} else {
|
||||||
}
|
childBrowserWindow.close();
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
browserWin.webContents.on('crashed', handleChildWindowCrashEvent);
|
browserWin.webContents.on('crashed', handleChildWindowCrashEvent);
|
||||||
|
@ -122,6 +122,7 @@
|
|||||||
"lodash.isequal": "4.5.0",
|
"lodash.isequal": "4.5.0",
|
||||||
"lodash.omit": "4.5.0",
|
"lodash.omit": "4.5.0",
|
||||||
"lodash.pick": "4.4.0",
|
"lodash.pick": "4.4.0",
|
||||||
|
"mmmagic": "0.5.0",
|
||||||
"parse-domain": "2.0.0",
|
"parse-domain": "2.0.0",
|
||||||
"ref": "1.3.5",
|
"ref": "1.3.5",
|
||||||
"shell-path": "2.1.0",
|
"shell-path": "2.1.0",
|
||||||
|
Loading…
Reference in New Issue
Block a user