From 48d0ea42adc670292e0106e427ae3ef9337dd0f2 Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Fri, 7 Apr 2017 17:34:08 -0700 Subject: [PATCH] Handle peer 'error' events correctly Handle peer 'error' events that are fired *before* the peer is emitted in a 'peer' event. Once the peer is emitted in a 'peer' event, then it's the consumer's responsibility to listen for errors. This fixes the most common error in WebTorrent Desktop according to our telemetry. --- lib/client/websocket-tracker.js | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/client/websocket-tracker.js b/lib/client/websocket-tracker.js index 058bc28..82d7be4 100644 --- a/lib/client/websocket-tracker.js +++ b/lib/client/websocket-tracker.js @@ -276,7 +276,7 @@ WebSocketTracker.prototype._onAnnounceResponse = function (data) { var peer if (data.offer && data.peer_id) { debug('creating peer (from remote offer)') - peer = new Peer({ + peer = self._createPeer({ trickle: false, config: self.client._rtcConfig, wrtc: self.client._wrtc @@ -389,7 +389,7 @@ WebSocketTracker.prototype._generateOffers = function (numwant, cb) { function generateOffer () { var offerId = randombytes(20).toString('hex') debug('creating peer (from _generateOffers)') - var peer = self.peers[offerId] = new Peer({ + var peer = self.peers[offerId] = self._createPeer({ initiator: true, trickle: false, config: self.client._rtcConfig, @@ -419,4 +419,28 @@ WebSocketTracker.prototype._generateOffers = function (numwant, cb) { } } +WebSocketTracker.prototype._createPeer = function (opts) { + var self = this + var peer = new Peer(opts) + + peer.once('error', onError) + peer.once('connect', onConnect) + + return peer + + // Handle peer 'error' events that are fired *before* the peer is emitted in + // a 'peer' event. + function onError (err) { + self.client.emit('warning', new Error('Connection error: ' + err.message)) + peer.destroy() + } + + // Once the peer is emitted in a 'peer' event, then it's the consumer's + // responsibility to listen for errors, so the listeners are removed here. + function onConnect () { + peer.removeListener('error', onError) + peer.removeListener('connect', onConnect) + } +} + function noop () {}