Skip to content

Commit 84e7345

Browse files
committed
fix the unhandled promise rejection bug
1 parent f55197e commit 84e7345

File tree

3 files changed

+31
-11
lines changed

3 files changed

+31
-11
lines changed

packages/ocap-kernel/src/remotes/RemoteHandle.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,14 +464,16 @@ export class RemoteHandle implements EndpointHandle {
464464

465465
// Set up timeout handling with AbortSignal
466466
const timeoutSignal = AbortSignal.timeout(30_000);
467+
let abortHandler: (() => void) | undefined;
467468
const timeoutPromise = new Promise<never>((_resolve, _reject) => {
468-
timeoutSignal.addEventListener('abort', () => {
469+
abortHandler = () => {
469470
// Clean up from pending redemptions map
470471
if (this.#pendingRedemptions.has(replyKey)) {
471472
this.#pendingRedemptions.delete(replyKey);
472473
}
473474
_reject(new Error('URL redemption timed out after 30 seconds'));
474-
});
475+
};
476+
timeoutSignal.addEventListener('abort', abortHandler);
475477
});
476478

477479
try {
@@ -487,6 +489,12 @@ export class RemoteHandle implements EndpointHandle {
487489
this.#pendingRedemptions.delete(replyKey);
488490
}
489491
throw error;
492+
} finally {
493+
// Clean up event listener to prevent unhandled rejection if operation
494+
// completes before timeout
495+
if (abortHandler) {
496+
timeoutSignal.removeEventListener('abort', abortHandler);
497+
}
490498
}
491499
}
492500

packages/ocap-kernel/src/remotes/network.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,26 @@ export async function initNetwork(
115115
timeoutMs = 10_000,
116116
): Promise<void> {
117117
const timeoutSignal = AbortSignal.timeout(timeoutMs);
118-
return Promise.race([
119-
channel.msgStream.write(message),
120-
new Promise<never>((_resolve, reject) => {
121-
timeoutSignal.addEventListener('abort', () => {
122-
reject(new Error(`Message send timed out after ${timeoutMs}ms`));
123-
});
124-
}),
125-
]);
118+
let abortHandler: (() => void) | undefined;
119+
const timeoutPromise = new Promise<never>((_resolve, reject) => {
120+
abortHandler = () => {
121+
reject(new Error(`Message send timed out after ${timeoutMs}ms`));
122+
};
123+
timeoutSignal.addEventListener('abort', abortHandler);
124+
});
125+
126+
try {
127+
return await Promise.race([
128+
channel.msgStream.write(message),
129+
timeoutPromise,
130+
]);
131+
} finally {
132+
// Clean up event listener to prevent unhandled rejection if operation
133+
// completes before timeout
134+
if (abortHandler) {
135+
timeoutSignal.removeEventListener('abort', abortHandler);
136+
}
137+
}
126138
}
127139

128140
/**

vitest.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ export default defineConfig({
130130
'packages/kernel-ui/**': {
131131
statements: 97.57,
132132
functions: 97.29,
133-
branches: 93.25,
133+
branches: 93.26,
134134
lines: 97.57,
135135
},
136136
'packages/kernel-utils/**': {

0 commit comments

Comments
 (0)