From 366a2f99a15660d45485637bbd868dd5ae4f4722 Mon Sep 17 00:00:00 2001 From: chh <1474479+chenhunghan@users.noreply.github.com> Date: Thu, 2 Sep 2021 13:20:18 +0300 Subject: [PATCH] Make ipc.boradcast not stopping at uncaught exceptions, improve typing, improve error logs (#3717) * Improve typing, print better error message instead of stop at throwing at view.getType(); continue to send to subframe even if one throws Signed-off-by: Hung-Han (Henry) Chen * Remove console.log Signed-off-by: Hung-Han (Henry) Chen * Remove extra line Signed-off-by: Hung-Han (Henry) Chen --- src/common/ipc/ipc.ts | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/common/ipc/ipc.ts b/src/common/ipc/ipc.ts index f93a9486aa..9ed51b7790 100644 --- a/src/common/ipc/ipc.ts +++ b/src/common/ipc/ipc.ts @@ -28,8 +28,9 @@ import { toJS } from "../utils/toJS"; import logger from "../../main/logger"; import { ClusterFrameInfo, clusterFrameMap } from "../cluster-frames"; import type { Disposer } from "../utils"; +import type remote from "@electron/remote"; -const remote = ipcMain ? null : require("@electron/remote"); +const electronRemote = ipcMain ? null : require("@electron/remote"); const subFramesChannel = "ipc:get-sub-frames"; @@ -48,9 +49,9 @@ function getSubFrames(): ClusterFrameInfo[] { } export function broadcastMessage(channel: string, ...args: any[]) { - const views = (webContents || remote?.webContents)?.getAllWebContents(); + const views: undefined | ReturnType | ReturnType = (webContents || electronRemote?.webContents)?.getAllWebContents(); - if (!views) return; + if (!views || !Array.isArray(views) || views.length === 0) return; args = args.map(sanitizePayload); ipcRenderer?.send(channel, ...args); @@ -63,15 +64,32 @@ export function broadcastMessage(channel: string, ...args: any[]) { subFramesP .then(subFrames => { for (const view of views) { - try { - logger.silly(`[IPC]: broadcasting "${channel}" to ${view.getType()}=${view.id}`, { args }); - view.send(channel, ...args); + let viewType = "unknown"; - for (const frameInfo of subFrames) { - view.sendToFrame([frameInfo.processId, frameInfo.frameId], channel, ...args); - } + // There will be a uncaught exception if the view is destroyed. + try { + viewType = view.getType(); + } catch { + // We can ignore the view destroyed exception as viewType is only used for logging. + } + + // Send message to views. + try { + logger.silly(`[IPC]: broadcasting "${channel}" to ${viewType}=${view.id}`, { args }); + view.send(channel, ...args); } catch (error) { - logger.error("[IPC]: failed to send IPC message", { error: String(error) }); + logger.error(`[IPC]: failed to send IPC message "${channel}" to view "${viewType}=${view.id}"`, { error: String(error) }); + } + + // Send message to subFrames of views. + for (const frameInfo of subFrames) { + logger.silly(`[IPC]: broadcasting "${channel}" to subframe "frameInfo.processId"=${frameInfo.processId} "frameInfo.frameId"=${frameInfo.frameId}`, { args }); + + try { + view.sendToFrame([frameInfo.processId, frameInfo.frameId], channel, ...args); + } catch (error) { + logger.error(`[IPC]: failed to send IPC message "${channel}" to view "${viewType}=${view.id}"'s subframe "frameInfo.processId"=${frameInfo.processId} "frameInfo.frameId"=${frameInfo.frameId}`, { error: String(error) }); + } } } });