Skip to content

Commit 36c9095

Browse files
authored
Merge pull request #369 from brendandburns/watch
Add some missing error handling.
2 parents 34cfa68 + c7892e3 commit 36c9095

File tree

2 files changed

+122
-0
lines changed

2 files changed

+122
-0
lines changed

src/watch.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export class DefaultRequest implements RequestInterface {
1818
}
1919

2020
export class Watch {
21+
public static SERVER_SIDE_CLOSE = { error: 'Connection closed on server' };
2122
public config: KubeConfig;
2223
private readonly requestImpl: RequestInterface;
2324

@@ -64,6 +65,10 @@ export class Watch {
6465
// ignore parse errors
6566
}
6667
});
68+
stream.on('error', (err) => {
69+
done(err);
70+
});
71+
stream.on('close', () => done(null));
6772
const req = this.requestImpl.webRequest(requestOptions, (error, response, body) => {
6873
if (error) {
6974
done(error);

src/watch_test.ts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,123 @@ describe('Watch', () => {
112112
expect(doneErr).to.deep.equal(errIn);
113113
});
114114

115+
it('should handle errors correctly', () => {
116+
const kc = new KubeConfig();
117+
Object.assign(kc, fakeConfig);
118+
const fakeRequestor = mock(DefaultRequest);
119+
const watch = new Watch(kc, instance(fakeRequestor));
120+
121+
const obj1 = {
122+
type: 'ADDED',
123+
object: {
124+
foo: 'bar',
125+
},
126+
};
127+
128+
const errIn = { error: 'err' };
129+
const fakeRequest = {
130+
pipe: (stream) => {
131+
stream.write(JSON.stringify(obj1) + '\n');
132+
stream.emit('error', errIn);
133+
},
134+
};
135+
136+
when(fakeRequestor.webRequest(anything(), anyFunction())).thenReturn(fakeRequest);
137+
138+
const path = '/some/path/to/object';
139+
140+
const receivedTypes: string[] = [];
141+
const receivedObjects: string[] = [];
142+
let doneCalled = false;
143+
let doneErr: any;
144+
145+
watch.watch(
146+
path,
147+
{},
148+
(phase: string, obj: string) => {
149+
receivedTypes.push(phase);
150+
receivedObjects.push(obj);
151+
},
152+
(err: any) => {
153+
doneCalled = true;
154+
doneErr = err;
155+
},
156+
);
157+
158+
verify(fakeRequestor.webRequest(anything(), anyFunction()));
159+
160+
const [opts, doneCallback] = capture(fakeRequestor.webRequest).last();
161+
const reqOpts: request.OptionsWithUri = opts as request.OptionsWithUri;
162+
163+
expect(reqOpts.uri).to.equal(`${server}${path}`);
164+
expect(reqOpts.method).to.equal('GET');
165+
expect(reqOpts.json).to.equal(true);
166+
167+
expect(receivedTypes).to.deep.equal([obj1.type]);
168+
expect(receivedObjects).to.deep.equal([obj1.object]);
169+
170+
expect(doneCalled).to.equal(true);
171+
expect(doneErr).to.deep.equal(errIn);
172+
});
173+
174+
it('should handle server side close correctly', () => {
175+
const kc = new KubeConfig();
176+
Object.assign(kc, fakeConfig);
177+
const fakeRequestor = mock(DefaultRequest);
178+
const watch = new Watch(kc, instance(fakeRequestor));
179+
180+
const obj1 = {
181+
type: 'ADDED',
182+
object: {
183+
foo: 'bar',
184+
},
185+
};
186+
187+
const fakeRequest = {
188+
pipe: (stream) => {
189+
stream.write(JSON.stringify(obj1) + '\n');
190+
stream.emit('close');
191+
},
192+
};
193+
194+
when(fakeRequestor.webRequest(anything(), anyFunction())).thenReturn(fakeRequest);
195+
196+
const path = '/some/path/to/object';
197+
198+
const receivedTypes: string[] = [];
199+
const receivedObjects: string[] = [];
200+
let doneCalled = false;
201+
let doneErr: any;
202+
203+
watch.watch(
204+
path,
205+
{},
206+
(phase: string, obj: string) => {
207+
receivedTypes.push(phase);
208+
receivedObjects.push(obj);
209+
},
210+
(err: any) => {
211+
doneCalled = true;
212+
doneErr = err;
213+
},
214+
);
215+
216+
verify(fakeRequestor.webRequest(anything(), anyFunction()));
217+
218+
const [opts, doneCallback] = capture(fakeRequestor.webRequest).last();
219+
const reqOpts: request.OptionsWithUri = opts as request.OptionsWithUri;
220+
221+
expect(reqOpts.uri).to.equal(`${server}${path}`);
222+
expect(reqOpts.method).to.equal('GET');
223+
expect(reqOpts.json).to.equal(true);
224+
225+
expect(receivedTypes).to.deep.equal([obj1.type]);
226+
expect(receivedObjects).to.deep.equal([obj1.object]);
227+
228+
expect(doneCalled).to.equal(true);
229+
expect(doneErr).to.be.null;
230+
});
231+
115232
it('should ignore JSON parse errors', () => {
116233
const kc = new KubeConfig();
117234
Object.assign(kc, fakeConfig);

0 commit comments

Comments
 (0)