diff --git a/client/client-constants.ts b/client/client-constants.ts index c221f45ad4..1fb79eb368 100644 --- a/client/client-constants.ts +++ b/client/client-constants.ts @@ -17,6 +17,10 @@ const urls = { dev: `file://${root}/client/splash-screen/splash-screen.html`, prod: `file://${root}/build/client/splash-screen/splash-screen.html`, }, + recover: { + dev: `file://${root}/client/recover-window/recover-window.html`, + prod: `file://${root}/build/client/recover-window/recover-window.html`, + }, icon: __dirname + "/../assets/images/icon.ico", }; diff --git a/client/core/global.ts b/client/core/global.ts index d7ce19cabb..4abf5e7bc0 100644 --- a/client/core/global.ts +++ b/client/core/global.ts @@ -1,12 +1,14 @@ import { AuthenticationWindow } from "../authentication"; import { MainWindow } from "../main-window"; +import { RecoverWindow } from "../recover-window"; import { SplashScreen } from "../splash-screen"; const splashScreen = new SplashScreen(); const authenticationWindow = new AuthenticationWindow(); +const recoverWindow = new RecoverWindow(); const mainWindow = new MainWindow(); /** * Set of unique windows used across the app */ -export const windows = { splashScreen, authentication: authenticationWindow, main: mainWindow }; +export const windows = { splashScreen, authentication: authenticationWindow, main: mainWindow, recover: recoverWindow }; diff --git a/client/main-window/main-window.ts b/client/main-window/main-window.ts index c431856b2f..6e341630f0 100644 --- a/client/main-window/main-window.ts +++ b/client/main-window/main-window.ts @@ -30,7 +30,7 @@ export class MainWindow extends UniqueWindow { }, }); const url = process.env.HOT ? devServerUrl : buildFileUrl; - + this._setupEvents(window); window.loadURL(url); const anyWindow = window as any; @@ -59,4 +59,22 @@ export class MainWindow extends UniqueWindow { return window; } + + private _setupEvents(window: Electron.BrowserWindow) { + window.webContents.on("crashed", (error: Error) => { + logger.error("There was a crash", error); + windows.recover.createWithError(error.message); + }); + + window.webContents.on("did-fail-load", (error) => { + windows.splashScreen.updateMessage( + "Fail to load! Make sure you built the app or are running the dev-server."); + logger.error("Fail to load", error); + }); + + window.on("unresponsive", (error: Error) => { + logger.error("There was a crash", error); + windows.recover.createWithError(error.message); + }); + } } diff --git a/client/main.ts b/client/main.ts index fde354240a..0e520c085f 100644 --- a/client/main.ts +++ b/client/main.ts @@ -1,9 +1,10 @@ -import { app, protocol } from "electron"; +import { app, ipcMain, protocol } from "electron"; import * as path from "path"; app.setPath("userData", path.join(app.getPath("appData"), "batch-labs")); import { windows } from "./core"; +import { logger } from "./logger"; // Create the browser window. function createWindow() { @@ -40,3 +41,25 @@ app.on("activate", () => { createWindow(); } }); + +ipcMain.once("exit", () => { + process.exit(1); +}); + +ipcMain.on("reload", () => { + // Destroy window and error window if applicable + windows.main.destroy(); + windows.recover.destroy(); + + // Show splash screen + windows.splashScreen.create(); + windows.splashScreen.updateMessage("Loading app"); + + // Reopen a new window + windows.main.create(); +}); + +process.on("uncaughtException", (error: Error) => { + logger.error("There was a uncaught exception", error); + windows.recover.createWithError(error.message); +}); diff --git a/client/recover-window/index.ts b/client/recover-window/index.ts new file mode 100644 index 0000000000..0c229bf3ec --- /dev/null +++ b/client/recover-window/index.ts @@ -0,0 +1 @@ +export * from "./recover-window"; diff --git a/client/recover-window/recover-window.html b/client/recover-window/recover-window.html new file mode 100644 index 0000000000..4a4d5c62e5 --- /dev/null +++ b/client/recover-window/recover-window.html @@ -0,0 +1,108 @@ + + + + + + + +
+
+ Oops! There was an error in batch labs +
+ +
+ Blabal lots off errors.... +
+
+ + + + diff --git a/client/recover-window/recover-window.ts b/client/recover-window/recover-window.ts new file mode 100644 index 0000000000..7e81480441 --- /dev/null +++ b/client/recover-window/recover-window.ts @@ -0,0 +1,51 @@ +import { BrowserWindow } from "electron"; +import { Constants } from "../client-constants"; +import { UniqueWindow } from "../core"; + +const urls = Constants.urls.recover; +const url = process.env.HOT ? urls.dev : urls.prod; + +export class RecoverWindow extends UniqueWindow { + private _currentMessage = ""; + + public createWithError(message: string) { + this.create(); + this.updateErrorMessage(message); + } + + public updateErrorMessage(message: string) { + this._currentMessage = message; + this._sendMessageToWindow(); + } + + public destroy() { + super.destroy(); + this.clearMessage(); + } + + public clearMessage() { + this.updateErrorMessage(""); + } + + protected createWindow() { + const window = new BrowserWindow({ + height: 440, + width: 440, + icon: Constants.urls.icon, + resizable: false, + titleBarStyle: "hidden", + frame: false, + }); + window.loadURL(url); + window.webContents.once("dom-ready", () => { + this._sendMessageToWindow(); + }); + return window; + } + + private _sendMessageToWindow() { + if (this._window) { + this._window.webContents.send("update-message", this._currentMessage); + } + } +}