Skip to content

Commit 8869fa5

Browse files
authored
Merge pull request #111 from kuzzleio/fix-rc7-110-handle-ws-error
Fix #110: Handle WebSocket close events
2 parents 3fd4c2b + 1378053 commit 8869fa5

File tree

6 files changed

+93
-26
lines changed

6 files changed

+93
-26
lines changed

src/kuzzle.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ Kuzzle.prototype.connect = function () {
340340
});
341341

342342
self.network.onConnectError(function (error) {
343-
var connectionError = new Error('Unable to connect to kuzzle server at "' + self.host + '"');
343+
var connectionError = new Error('Unable to connect to kuzzle proxy server at "' + self.host + '"');
344344

345345
connectionError.internal = error;
346346
self.state = 'error';

src/networkWrapper/wrappers/wsbrowsers.js

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,17 @@ function WSBrowsers(host, port, ssl) {
4040
}
4141
};
4242

43-
this.client.onclose = function () {
44-
poke(self.listeners, 'disconnect');
45-
};
46-
47-
this.client.onerror = function () {
48-
if (autoReconnect) {
49-
self.retrying = true;
50-
setTimeout(function () {
51-
self.connect(autoReconnect, reconnectionDelay);
52-
}, reconnectionDelay);
43+
this.client.onclose = function (code, message) {
44+
if (code === 1000) {
45+
poke(self.listeners, 'disconnect');
46+
}
47+
else {
48+
onClientError.call(self, autoReconnect, reconnectionDelay, message);
5349
}
50+
};
5451

55-
poke(self.listeners, 'error');
52+
this.client.onerror = function (error) {
53+
onClientError.call(self, autoReconnect, reconnectionDelay, error);
5654
};
5755

5856
this.client.onmessage = function (payload) {
@@ -234,4 +232,25 @@ function poke (listeners, roomId, payload) {
234232
}
235233
}
236234

235+
/**
236+
* Called when the connection closes with an error state
237+
*
238+
* @param {boolean} autoReconnect
239+
* @param {number} reconnectionDelay
240+
* @param {string|Object} message
241+
*/
242+
function onClientError(autoReconnect, reconnectionDelay, message) {
243+
var self = this;
244+
245+
if (autoReconnect) {
246+
self.retrying = true;
247+
setTimeout(function () {
248+
self.connect(autoReconnect, reconnectionDelay);
249+
}, reconnectionDelay);
250+
}
251+
252+
poke(self.listeners, 'error', message);
253+
}
254+
255+
237256
module.exports = WSBrowsers;

src/networkWrapper/wrappers/wsnode.js

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,17 @@ function WSNode(host, port, ssl) {
4343
}
4444
});
4545

46-
this.client.on('close', function () {
47-
poke(self.listeners, 'disconnect');
48-
});
49-
50-
this.client.on('error', function () {
51-
if (autoReconnect) {
52-
self.retrying = true;
53-
setTimeout(function () {
54-
self.connect(autoReconnect, reconnectionDelay);
55-
}, reconnectionDelay);
46+
this.client.on('close', function (code, message) {
47+
if (code === 1000) {
48+
poke(self.listeners, 'disconnect');
49+
}
50+
else {
51+
onClientError.call(self, autoReconnect, reconnectionDelay, message);
5652
}
53+
});
5754

58-
poke(self.listeners, 'error');
55+
this.client.on('error', function (error) {
56+
onClientError.call(self, autoReconnect, reconnectionDelay, error);
5957
});
6058

6159
this.client.on('message', function (payload) {
@@ -237,4 +235,24 @@ function poke (listeners, roomId, payload) {
237235
}
238236
}
239237

238+
/**
239+
* Called when the connection closes with an error state
240+
*
241+
* @param {boolean} autoReconnect
242+
* @param {number} reconnectionDelay
243+
* @param {string|Object} message
244+
*/
245+
function onClientError(autoReconnect, reconnectionDelay, message) {
246+
var self = this;
247+
248+
if (autoReconnect) {
249+
self.retrying = true;
250+
setTimeout(function () {
251+
self.connect(autoReconnect, reconnectionDelay);
252+
}, reconnectionDelay);
253+
}
254+
255+
poke(self.listeners, 'error', message);
256+
}
257+
240258
module.exports = WSNode;

test/kuzzle/constructor.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ describe('Kuzzle constructor', () => {
306306
kuzzle = new Kuzzle('nowhere', function (err, res) {
307307
try {
308308
should(err).be.instanceOf(Error);
309-
should(err.message).be.exactly('Unable to connect to kuzzle server at "nowhere"');
309+
should(err.message).be.exactly('Unable to connect to kuzzle proxy server at "nowhere"');
310310
should(err.internal).be.exactly('error');
311311
should(res).be.undefined();
312312
should(kuzzle.state).be.exactly('error');

test/network/wsbrowsers.test.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,27 @@ describe('WebSocket Browsers networking module', () => {
124124
should(wsbrowsers.listeners.disconnect.length).be.eql(1);
125125

126126
wsbrowsers.connect();
127-
clientStub.onclose();
127+
clientStub.onclose(1000);
128128

129129
should(cb.calledOnce).be.true();
130130
should(wsbrowsers.listeners.disconnect.length).be.eql(1);
131131
});
132132

133+
it('should call error listeners on a disconnect event with an abnormal websocket code', () => {
134+
var cb = sinon.stub();
135+
136+
wsbrowsers.retrying = false;
137+
wsbrowsers.onConnectError(cb);
138+
should(wsbrowsers.listeners.error.length).be.eql(1);
139+
140+
wsbrowsers.connect();
141+
clientStub.onclose(4666, 'foobar');
142+
143+
should(cb.calledOnce).be.true();
144+
should(cb.calledWith('foobar'));
145+
should(wsbrowsers.listeners.error.length).be.eql(1);
146+
});
147+
133148
it('should be able to register ephemeral callbacks on an event', () => {
134149
var
135150
cb = sinon.stub(),

test/network/wsnode.test.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,27 @@ describe('WebSocket NodeJS networking module', () => {
124124
should(wsnode.listeners.disconnect.length).be.eql(1);
125125

126126
wsnode.connect();
127-
clientStub.emit('close');
127+
clientStub.emit('close', 1000);
128128

129129
should(cb.calledOnce).be.true();
130130
should(wsnode.listeners.disconnect.length).be.eql(1);
131131
});
132132

133+
it('should call error listeners on a disconnect event with an abnormal websocket code', () => {
134+
var cb = sinon.stub();
135+
136+
wsnode.retrying = false;
137+
wsnode.onConnectError(cb);
138+
should(wsnode.listeners.error.length).be.eql(1);
139+
140+
wsnode.connect();
141+
clientStub.emit('close', 4666, 'foobar');
142+
143+
should(cb.calledOnce).be.true();
144+
should(cb.calledWith('foobar'));
145+
should(wsnode.listeners.error.length).be.eql(1);
146+
});
147+
133148
it('should be able to register ephemeral callbacks on an event', () => {
134149
var
135150
cb = sinon.stub(),

0 commit comments

Comments
 (0)