Skip to content

Commit d02aeaf

Browse files
committed
fix: timeoutSignal is lost after being overriden with controller.signal
1 parent 8c13428 commit d02aeaf

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

src/watch.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { KubeConfig } from './config.js';
66
export class Watch {
77
public static SERVER_SIDE_CLOSE: object = { error: 'Connection closed on server' };
88
public config: KubeConfig;
9+
private defaultRequestTimeoutMs: number = 30000;
910

1011
public constructor(config: KubeConfig) {
1112
this.config = config;
@@ -39,7 +40,7 @@ export class Watch {
3940
const requestInit = await this.config.applyToFetchOptions({});
4041

4142
const controller = new AbortController();
42-
const timeoutSignal = AbortSignal.timeout(30000);
43+
const timeoutSignal = AbortSignal.timeout(this.defaultRequestTimeoutMs);
4344
requestInit.signal = AbortSignal.any([controller.signal, timeoutSignal]);
4445
requestInit.method = 'GET';
4546

src/watch_test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,41 @@ describe('Watch', () => {
452452
s.done();
453453
});
454454

455+
it('should timeout when server takes too long to respond', async (t) => {
456+
const kc = await setupMockSystem(t, (_req: any, _res: any) => {
457+
// Don't respond - simulate a hanging server
458+
});
459+
const watch = new Watch(kc);
460+
// Hack around type system to make the default timeout shorter.
461+
(watch as any).timeoutMs = 100;
462+
463+
let doneCalled = false;
464+
let doneErr: any;
465+
466+
let doneResolve: () => void;
467+
const donePromise = new Promise<void>((resolve) => {
468+
doneResolve = resolve;
469+
});
470+
471+
await watch.watch(
472+
'/some/path/to/object',
473+
{},
474+
() => {
475+
throw new Error('Unexpected data received - timeout should have occurred before any data');
476+
},
477+
(err: any) => {
478+
doneCalled = true;
479+
doneErr = err;
480+
doneResolve();
481+
},
482+
);
483+
484+
await donePromise;
485+
486+
strictEqual(doneCalled, true);
487+
strictEqual(doneErr.name, 'AbortError');
488+
});
489+
455490
it('should throw on empty config', async () => {
456491
const kc = new KubeConfig();
457492
const watch = new Watch(kc);

0 commit comments

Comments
 (0)