aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2021-12-26 21:28:32 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2021-12-26 21:36:35 +0100
commit67f48ebf845a40e73b4933f8b28b55a0a6019be6 (patch)
tree29308a4220e034ef4e0eb31e36a0c975cdef37e5
parentrefactor: Less boilerplate around SophieRenderer (diff)
downloadsophie-67f48ebf845a40e73b4933f8b28b55a0a6019be6.tar.gz
sophie-67f48ebf845a40e73b4933f8b28b55a0a6019be6.tar.zst
sophie-67f48ebf845a40e73b4933f8b28b55a0a6019be6.zip
refactor: Improve error handling in preload
-rw-r--r--packages/preload/src/contextBridge/SophieRendererImpl.ts58
1 files changed, 43 insertions, 15 deletions
diff --git a/packages/preload/src/contextBridge/SophieRendererImpl.ts b/packages/preload/src/contextBridge/SophieRendererImpl.ts
index 5d29071..153fdd1 100644
--- a/packages/preload/src/contextBridge/SophieRendererImpl.ts
+++ b/packages/preload/src/contextBridge/SophieRendererImpl.ts
@@ -32,35 +32,63 @@ import { RendererToMainIpcService } from '../services/RendererToMainIpcService';
32class SophieRendererImpl implements SophieRenderer { 32class SophieRendererImpl implements SophieRenderer {
33 readonly #ipcService: RendererToMainIpcService; 33 readonly #ipcService: RendererToMainIpcService;
34 34
35 #onSharedStoreChangeCalled = false;
36
35 #listener: SharedStoreListener | null = null; 37 #listener: SharedStoreListener | null = null;
36 38
37 constructor(ipcService: RendererToMainIpcService) { 39 constructor(ipcService: RendererToMainIpcService) {
38 this.#ipcService = ipcService; 40 this.#ipcService = ipcService;
39 ipcService.onSharedStorePatch((patch) => { 41 ipcService.onSharedStorePatch((patch) => {
40 // `mobx-state-tree` will validate the patch, so we can safely cast here. 42 try {
41 this.#listener?.onPatch(patch as IJsonPatch); 43 // `mobx-state-tree` will validate the patch, so we can safely cast here.
44 this.#listener?.onPatch(patch as IJsonPatch);
45 } catch (err) {
46 console.log('Shared store listener onPatch failed', err);
47 }
42 }); 48 });
43 } 49 }
44 50
45 onSharedStoreChange(listener: SharedStoreListener): void { 51 async #setSharedStoreChangeListener(listener: SharedStoreListener): Promise<void> {
46 this.#ipcService.getSharedStoreSnapshot().then((snapshot) => { 52 let snapshot: unknown;
47 if (sharedStore.is(snapshot)) { 53 try {
54 snapshot = await this.#ipcService.getSharedStoreSnapshot();
55 } catch (err) {
56 console.error('Failed to get initial shared store snapshot', err);
57 return;
58 }
59 if (sharedStore.is(snapshot)) {
60 try {
48 listener.onSnapshot(snapshot); 61 listener.onSnapshot(snapshot);
49 this.#listener = listener; 62 } catch (err) {
50 } else { 63 console.error('Shared store listener onSnapshot failed', err);
51 console.error('Got invalid initial shared store snapshot', snapshot); 64 return;
52 } 65 }
53 }).catch((err) => { 66 this.#listener = listener;
54 console.error('Failed set initial shared store snapshot', err); 67 return;
68 }
69 console.error('Got invalid initial shared store snapshot', snapshot);
70 }
71
72 onSharedStoreChange(listener: SharedStoreListener): void {
73 if (this.#onSharedStoreChangeCalled) {
74 throw new Error('Shared store change listener was already set');
75 }
76 this.#setSharedStoreChangeListener(listener).catch((err) => {
77 console.log('Failed to set shared store change listener', err);
55 }); 78 });
56 } 79 }
57 80
58 dispatchAction(actionToDispatch: Action): void { 81 dispatchAction(actionToDispatch: Action): void {
59 const parsedAction = action.safeParse(actionToDispatch); 82 // Let the full zod parse error bubble up to the main world,
60 if (parsedAction.success) { 83 // since all data it may contain was provided from the main world.
61 this.#ipcService.dispatchAction(parsedAction.data); 84 const parsedAction = action.parse(actionToDispatch);
62 } else { 85 try {
63 console.error('Trying to dispatch invalid action', actionToDispatch, parsedAction.error); 86 this.#ipcService.dispatchAction(parsedAction);
87 } catch (err) {
88 // Do not leak IPC failure details into the main world.
89 const message = 'Failed to dispatch action';
90 console.error(message, actionToDispatch, err);
91 throw new Error(message);
64 } 92 }
65 } 93 }
66} 94}