DEV Community

Or Yaacov
Or Yaacov

Posted on

How to pass exceptions in Electron.js from main process to renderer and other way around

Image description

If you struggled as well with "bubbling" exceptions between IpcMain and IpcRenderer in electron.js here is a self-exploratory, and simple solution that I created to solve this issue:

import {ipcMain, IpcMainInvokeEvent, ipcRenderer} from 'electron';

export interface channelMessage<T> {
  message?: T;
  error?: any;
}

export function handleMessageFromRenderer<T>(channel: string, listener: (event: IpcMainInvokeEvent, ...args: any[]) => Promise<void> | any) {
  ipcMain.handle(channel, async (event, args) => {
    const response: channelMessage<T> = {};

    try {
      response.message = await listener(event, args);
    } catch (e) {
      response.error = e;
    }

    return response;
  });
}

export async function sendMessageToMain(channel: string, ...args: any[]): Promise<any> {
  const {message, error} = await ipcRenderer.invoke(channel, ...args);
  if (error) {
    throw error;
  }

  return message;
}
Enter fullscreen mode Exit fullscreen mode

now instead of passing a message using ipcRenderer.invoke and icpMain.handle you can just use sendMessageToMain and sendMessageToMain

as in the following example:

xport const settingChannels = {
  openLogFile: 'open-log-file',
  updateApplication: 'update-application',
};

export const settingsApi = {
  openLogFile: async () => {
    await sendMessageToMain(settingChannels.openLogFile);
  },
  updateApplication: async (version) => {
    await sendMessageToMain(settingChannels.updateApplication, {version});
  },
 };

export function registerSettingsApi() {
  log.debug('registering settings apis');

  handleMessageFromRenderer(settingChannels.openLogFile, async (event): Promise<void> => {
    log.trace('handling open log');
    await settingsHandler.openLogFile();
  });

  handleMessageFromRenderer(settingChannels.updateApplication, async (event, args): Promise<void> => {
    log.trace('handling start app update');
    await settingsHandler.updateApplication(args.version);
  });
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)