Skip to content

Commit 7a2aa3c

Browse files
committed
fix the unhandled promise rejection bug
1 parent df0d74e commit 7a2aa3c

File tree

3 files changed

+35
-15
lines changed

3 files changed

+35
-15
lines changed

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

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

448448
// Set up timeout handling with AbortSignal
449449
const timeoutSignal = AbortSignal.timeout(30_000);
450+
let abortHandler: (() => void) | undefined;
450451
const timeoutPromise = new Promise<never>((_resolve, _reject) => {
451-
timeoutSignal.addEventListener('abort', () => {
452+
abortHandler = () => {
452453
// Clean up from pending redemptions map
453454
if (this.#pendingRedemptions.has(replyKey)) {
454455
this.#pendingRedemptions.delete(replyKey);
455456
}
456457
_reject(new Error('URL redemption timed out after 30 seconds'));
457-
});
458+
};
459+
timeoutSignal.addEventListener('abort', abortHandler);
458460
});
459461

460462
try {
@@ -470,6 +472,12 @@ export class RemoteHandle implements EndpointHandle {
470472
this.#pendingRedemptions.delete(replyKey);
471473
}
472474
throw error;
475+
} finally {
476+
// Clean up event listener to prevent unhandled rejection if operation
477+
// completes before timeout
478+
if (abortHandler) {
479+
timeoutSignal.removeEventListener('abort', abortHandler);
480+
}
473481
}
474482
}
475483

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

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,26 @@ export async function initNetwork(
131131
timeoutMs = 10_000,
132132
): Promise<void> {
133133
const timeoutSignal = AbortSignal.timeout(timeoutMs);
134-
return Promise.race([
135-
channel.msgStream.write(message),
136-
new Promise<never>((_resolve, reject) => {
137-
timeoutSignal.addEventListener('abort', () => {
138-
reject(new Error(`Message send timed out after ${timeoutMs}ms`));
139-
});
140-
}),
141-
]);
134+
let abortHandler: (() => void) | undefined;
135+
const timeoutPromise = new Promise<never>((_resolve, reject) => {
136+
abortHandler = () => {
137+
reject(new Error(`Message send timed out after ${timeoutMs}ms`));
138+
};
139+
timeoutSignal.addEventListener('abort', abortHandler);
140+
});
141+
142+
try {
143+
return await Promise.race([
144+
channel.msgStream.write(message),
145+
timeoutPromise,
146+
]);
147+
} finally {
148+
// Clean up event listener to prevent unhandled rejection if operation
149+
// completes before timeout
150+
if (abortHandler) {
151+
timeoutSignal.removeEventListener('abort', abortHandler);
152+
}
153+
}
142154
}
143155

144156
/**

vitest.config.ts

Lines changed: 5 additions & 5 deletions
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/**': {
@@ -158,10 +158,10 @@ export default defineConfig({
158158
lines: 22.22,
159159
},
160160
'packages/ocap-kernel/**': {
161-
statements: 96.61,
162-
functions: 98.53,
163-
branches: 97.74,
164-
lines: 96.61,
161+
statements: 96.62,
162+
functions: 98.54,
163+
branches: 97.66,
164+
lines: 96.62,
165165
},
166166
'packages/omnium-gatherum/**': {
167167
statements: 5.67,

0 commit comments

Comments
 (0)