Skip to content

Commit 3960d80

Browse files
dgolovinbenoitf
andauthored
fix: update encodeIpcError method to correctly handle Error instance (podman-desktop#10964)
Co-authored-by: Florent BENOIT <[email protected]> Signed-off-by: Denis Golovin <[email protected]>
1 parent 66ee7cd commit 3960d80

File tree

2 files changed

+32
-17
lines changed

2 files changed

+32
-17
lines changed

packages/main/src/plugin/index.spec.ts

+26
Original file line numberDiff line numberDiff line change
@@ -387,3 +387,29 @@ test('Pull image creates a task', async () => {
387387
} as PullEvent);
388388
expect(createTaskSpy.mock.results[0]?.value.status).toBe('success');
389389
});
390+
391+
test('ipcMain.handle returns caught error as is if it is instance of Error', async () => {
392+
const createTaskSpy = vi.spyOn(TaskManager.prototype, 'execute');
393+
await pluginSystem.initExtensions(new Emitter<ConfigurationRegistry>());
394+
const handle = handlers.get('tasks:execute');
395+
const errorInstance = new Error('error');
396+
createTaskSpy.mockImplementation(() => {
397+
throw errorInstance;
398+
});
399+
400+
const handleReturn = await handle(undefined, '1');
401+
expect(handleReturn.error).toEqual(errorInstance);
402+
});
403+
404+
test('ipcMain.handle returns caught error as objects message property if it is not instance of error', async () => {
405+
const createTaskSpy = vi.spyOn(TaskManager.prototype, 'execute');
406+
await pluginSystem.initExtensions(new Emitter<ConfigurationRegistry>());
407+
const handle = handlers.get('tasks:execute');
408+
const nonErrorInstance = 'error';
409+
createTaskSpy.mockImplementation(() => {
410+
throw nonErrorInstance;
411+
});
412+
413+
const handleReturn = await handle(undefined, '1');
414+
expect(handleReturn.error).toEqual({ message: nonErrorInstance });
415+
});

packages/main/src/plugin/index.ts

+6-17
Original file line numberDiff line numberDiff line change
@@ -246,27 +246,16 @@ export class PluginSystem {
246246
return window.webContents;
247247
}
248248

249-
// encode the error to be sent over IPC
250-
// this is needed because on the client it will display
251-
// a generic error message 'Error invoking remote method' and
252-
// it's not useful for end user
253-
encodeIpcError(e: unknown): { name?: string; message: unknown; extra?: Record<string, unknown> } {
254-
let builtError;
255-
if (e instanceof Error) {
256-
builtError = { name: e.name, message: e.message, extra: { ...e } };
257-
} else {
258-
builtError = { message: e };
259-
}
260-
return builtError;
261-
}
262-
263249
// eslint-disable-next-line @typescript-eslint/no-explicit-any
264-
ipcHandle(channel: string, listener: (event: IpcMainInvokeEvent, ...args: any[]) => Promise<void> | any): any {
250+
ipcHandle(channel: string, listener: (event: IpcMainInvokeEvent, ...args: any[]) => Promise<void> | any): void {
265251
ipcMain.handle(channel, async (...args) => {
266252
try {
267253
return { result: await Promise.resolve(listener(...args)) };
268-
} catch (e) {
269-
return { error: this.encodeIpcError(e) };
254+
} catch (error) {
255+
// From error instance only message property will get through.
256+
// Sending non error instance as a message property of an object triggers
257+
// coercion of message property to String.
258+
return error instanceof Error ? { error } : { error: { message: error } };
270259
}
271260
});
272261
}

0 commit comments

Comments
 (0)