fixes handling networking errors and retries. Adds tests
This commit is contained in:
parent
50a29909ba
commit
bbac45ee7a
3 changed files with 117 additions and 35 deletions
|
|
@ -223,17 +223,24 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras
|
||||||
key: privateKey.getIdKey()
|
key: privateKey.getIdKey()
|
||||||
};
|
};
|
||||||
self.network.cleanUp();
|
self.network.cleanUp();
|
||||||
|
|
||||||
|
// This is a hack to reconize if the connection was rejected or the peer wasn't there.
|
||||||
|
var connectedOnce = false;
|
||||||
|
self.network.on('connected', function(sender, data) {
|
||||||
|
connectedOnce = true;
|
||||||
|
});
|
||||||
|
self.network.on('onlyYou', function(sender, data) {
|
||||||
|
return cb(connectedOnce ? 'walletFull' : 'joinError');
|
||||||
|
});
|
||||||
|
|
||||||
|
self.network.on('serverError', function() {
|
||||||
|
console.log('[WalletFactory.js.236]'); //TODO
|
||||||
|
return cb('joinError');
|
||||||
|
});
|
||||||
|
|
||||||
self.network.start(opts, function() {
|
self.network.start(opts, function() {
|
||||||
self.network.connectTo(s.pubKey);
|
self.network.connectTo(s.pubKey);
|
||||||
|
|
||||||
// This is a hack to reconize if the connection was rejected or the peer wasn't there.
|
|
||||||
var connectedOnce = false;
|
|
||||||
self.network.on('connected', function(sender, data) {
|
|
||||||
connectedOnce = true;
|
|
||||||
});
|
|
||||||
self.network.on('onlyYou', function(sender, data) {
|
|
||||||
return cb(connectedOnce ? 'walletFull' : 'joinError');
|
|
||||||
});
|
|
||||||
self.network.on('data', function(sender, data) {
|
self.network.on('data', function(sender, data) {
|
||||||
if (data.type === 'walletId') {
|
if (data.type === 'walletId') {
|
||||||
if (data.networkName !== self.networkName) {
|
if (data.networkName !== self.networkName) {
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ Network.prototype.cleanUp = function() {
|
||||||
}
|
}
|
||||||
this.closing = 0;
|
this.closing = 0;
|
||||||
this.tries = 0;
|
this.tries = 0;
|
||||||
|
this.removeAllListeners();
|
||||||
};
|
};
|
||||||
|
|
||||||
Network.parent = EventEmitter;
|
Network.parent = EventEmitter;
|
||||||
|
|
@ -259,35 +260,38 @@ Network.prototype._setupConnectionHandlers = function(dataConn, toCopayerId) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Network.prototype._setupPeerHandlers = function(openCallback) {
|
Network.prototype._handlePeerOpen = function(openCallback) {
|
||||||
var self = this;
|
this.connectedPeers = [this.peerId];
|
||||||
var p = this.peer;
|
this.copayerForPeer[this.peerId] = this.copayerId;
|
||||||
|
return openCallback();
|
||||||
p.on('open', function() {
|
|
||||||
self.connectedPeers = [self.peerId];
|
|
||||||
self.copayerForPeer[self.peerId] = self.copayerId;
|
|
||||||
return openCallback();
|
|
||||||
});
|
|
||||||
|
|
||||||
p.on('error', function(err) {
|
|
||||||
console.log('RECV ERROR: ', err); //TODO
|
|
||||||
if (!err.message.match(/Could\snot\sconnect\sto peer/)) {
|
|
||||||
self.criticalError = err.message;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
p.on('connection', function(dataConn) {
|
|
||||||
if (self.connectedPeers.length >= self.maxPeers) {
|
|
||||||
dataConn.on('open', function() {
|
|
||||||
dataConn.close();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
self._setInboundPeerAuth(dataConn.peer, false);
|
|
||||||
self._setupConnectionHandlers(dataConn);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Network.prototype._handlePeerError = function(err) {
|
||||||
|
console.log('RECV ERROR: ', err);
|
||||||
|
if (err.message.match(/Could\snot\sconnect\sto peer/)) {
|
||||||
|
this._checkAnyPeer();
|
||||||
|
} else {
|
||||||
|
this.criticalError = err.message;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Network.prototype._handlePeerConnection = function(dataConn) {
|
||||||
|
if (this.connectedPeers.length >= self.maxPeers) {
|
||||||
|
dataConn.on('open', function() {
|
||||||
|
dataConn.close();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this._setInboundPeerAuth(dataConn.peer, false);
|
||||||
|
this._setupConnectionHandlers(dataConn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Network.prototype._setupPeerHandlers = function(openCallback) {
|
||||||
|
var p = this.peer;
|
||||||
|
p.on('open', this._handlePeerOpen.bind(openCallback));
|
||||||
|
p.on('error', this._handlePeerError);
|
||||||
|
p.on('connection', this._handlePeerConnection);
|
||||||
|
};
|
||||||
|
|
||||||
Network.prototype._addCopayerMap = function(peerId, copayerId) {
|
Network.prototype._addCopayerMap = function(peerId, copayerId) {
|
||||||
if (!this.copayerForPeer[peerId]) {
|
if (!this.copayerForPeer[peerId]) {
|
||||||
|
|
@ -297,7 +301,6 @@ Network.prototype._addCopayerMap = function(peerId, copayerId) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Network.prototype._setInboundPeerAuth = function(peerId, isAuthenticated) {
|
Network.prototype._setInboundPeerAuth = function(peerId, isAuthenticated) {
|
||||||
this.isInboundPeerAuth[peerId] = isAuthenticated;
|
this.isInboundPeerAuth[peerId] = isAuthenticated;
|
||||||
};
|
};
|
||||||
|
|
@ -349,12 +352,14 @@ Network.prototype.start = function(opts, openCallback) {
|
||||||
self.peer = new Peer(self.peerId, self.opts);
|
self.peer = new Peer(self.peerId, self.opts);
|
||||||
self.started = true;
|
self.started = true;
|
||||||
self._setupPeerHandlers(openCallback);
|
self._setupPeerHandlers(openCallback);
|
||||||
|
|
||||||
setTimeout(setupPeer, 3000); // Schedule retry
|
setTimeout(setupPeer, 3000); // Schedule retry
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (self.criticalError && self.criticalError.match(/taken/)) {
|
if (self.criticalError && self.criticalError.match(/taken/)) {
|
||||||
self.criticalError = ' Looks like you are already connected to this wallet please close all other Copay Wallets '
|
self.criticalError = ' Looks like you are already connected to this wallet please close all other Copay Wallets '
|
||||||
}
|
}
|
||||||
|
|
||||||
self.emit('serverError', self.criticalError);
|
self.emit('serverError', self.criticalError);
|
||||||
self.cleanUp();
|
self.cleanUp();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ describe('Network / WebRTC', function() {
|
||||||
n.cleanUp.calledOnce.should.equal(true);
|
n.cleanUp.calledOnce.should.equal(true);
|
||||||
WebRTC.prototype.cleanUp = save;
|
WebRTC.prototype.cleanUp = save;
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#cleanUp', function() {
|
describe('#cleanUp', function() {
|
||||||
|
|
@ -44,8 +43,79 @@ describe('Network / WebRTC', function() {
|
||||||
expect(n.privkey).to.equal(null);
|
expect(n.privkey).to.equal(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should remove handlers', function() {
|
||||||
|
var n = new WebRTC();
|
||||||
|
var save = WebRTC.prototype.removeAllListeners;
|
||||||
|
var spy = WebRTC.prototype.removeAllListeners = sinon.spy();
|
||||||
|
n.cleanUp();
|
||||||
|
spy.calledOnce.should.equal(true);
|
||||||
|
WebRTC.prototype.removeAllListeners = save;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('#_setupPeerHandlers', function() {
|
||||||
|
var n = new WebRTC();
|
||||||
|
n.peer = {};
|
||||||
|
var spy = n.peer.on = sinon.spy();
|
||||||
|
it('should setup handlers', function() {
|
||||||
|
n._setupPeerHandlers();
|
||||||
|
spy.calledWith('connection').should.equal(true);
|
||||||
|
spy.calledWith('open').should.equal(true);
|
||||||
|
spy.calledWith('error').should.equal(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#_handlePeerOpen', function() {
|
||||||
|
var n = new WebRTC();
|
||||||
|
it('should call openCallback handler', function(done) {
|
||||||
|
n.peerId = 1;
|
||||||
|
n.copayerId = 2;
|
||||||
|
n._handlePeerOpen(function() {
|
||||||
|
n.connectedPeers.should.deep.equal([1]);
|
||||||
|
n.copayerForPeer.should.deep.equal({
|
||||||
|
1: 2
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#_handlePeerError', function() {
|
||||||
|
var log = console.log;
|
||||||
|
var n = new WebRTC();
|
||||||
|
it('should call _checkAnyPeer on could not connect error', function() {
|
||||||
|
var save = n._checkAnyPeer;
|
||||||
|
var spy = n._checkAnyPeer = sinon.spy();
|
||||||
|
var logSpy = console.log = sinon.spy();
|
||||||
|
n._handlePeerError({
|
||||||
|
message: 'Could not connect to peer xxx'
|
||||||
|
});
|
||||||
|
console.log = log;
|
||||||
|
spy.called.should.equal(true);
|
||||||
|
logSpy.called.should.equal(true);
|
||||||
|
n._checkAnyPeer = save;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call not call _checkAnyPeer other error', function() {
|
||||||
|
var save = n._checkAnyPeer;
|
||||||
|
var spy = n._checkAnyPeer = sinon.spy();
|
||||||
|
var otherMessage = 'Could connect to peer xxx';
|
||||||
|
var logSpy = console.log = sinon.spy();
|
||||||
|
n._handlePeerError({
|
||||||
|
message: otherMessage,
|
||||||
|
});
|
||||||
|
console.log = log;
|
||||||
|
spy.called.should.equal(false);
|
||||||
|
n.criticalError.should.equal(otherMessage);
|
||||||
|
logSpy.called.should.equal(true);
|
||||||
|
n._checkAnyPeer = save;
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
describe('#_encode', function() {
|
describe('#_encode', function() {
|
||||||
|
|
||||||
it('should encode data successfully', function() {
|
it('should encode data successfully', function() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue