diff --git a/modules/statistics/CallStats.js b/modules/statistics/CallStats.js index e91932832..3ba54286f 100644 --- a/modules/statistics/CallStats.js +++ b/modules/statistics/CallStats.js @@ -5,20 +5,35 @@ var jsSHA = require('jssha'); var io = require('socket.io-client'); var callStats = null; -// getUserMedia calls happen before CallStats init -// so if there are any getUserMedia errors, we store them in this array +/** + * @const + * @see http://www.callstats.io/api/#enumeration-of-wrtcfuncnames + */ +var wrtcFuncNames = { + createOffer: "createOffer", + createAnswer: "createAnswer", + setLocalDescription: "setLocalDescription", + setRemoteDescription: "setRemoteDescription", + addIceCandidate: "addIceCandidate", + getUserMedia: "getUserMedia" +}; + +// some errors may happen before CallStats init +// in this case we accumulate them in this array // and send them to callstats on init -var pendingUserMediaErrors = []; +var pendingErrors = []; function initCallback (err, msg) { - console.log("Initializing Status: err="+err+" msg="+msg); + console.log("CallStats Status: err=" + err + " msg=" + msg); } +var callStatsIntegrationEnabled = config.callStatsID && config.callStatsSecret; + var CallStats = { init: function (jingleSession) { - - if(!config.callStatsID || !config.callStatsSecret || callStats !== null) + if(!callStatsIntegrationEnabled || callStats !== null) { return; + } callStats = new callstats($, io, jsSHA); @@ -44,10 +59,12 @@ var CallStats = { this.confID, this.pcCallback.bind(this)); - // notify callstats about getUserMedia failures if there were any - if (pendingUserMediaErrors.length) { - pendingUserMediaErrors.forEach(this.sendGetUserMediaFailed, this); - pendingUserMediaErrors.length = 0; + // notify callstats about failures if there were any + if (pendingErrors.length) { + pendingErrors.forEach(function (error) { + this._reportError(error.type, error.error, error.pc); + }, this); + pendingErrors.length = 0; } }, pcCallback: function (err, msg) { @@ -109,84 +126,76 @@ var CallStats = { this.confID, feedbackJSON); }, + _reportError: function (type, e, pc) { + if (callStats) { + callStats.reportError(pc, this.confID, type, e); + } else if (callStatsIntegrationEnabled) { + pendingErrors.push({ + type: type, + error: e, + pc: pc + }); + } + // else just ignore it + }, + /** * Notifies CallStats that getUserMedia failed. * * @param {Error} e error to send */ sendGetUserMediaFailed: function (e) { - if(!callStats) { - pendingUserMediaErrors.push(e); - return; - } - callStats.reportError(this.peerconnection, this.confID, - callStats.webRTCFunctions.getUserMedia, e); + this._reportError(wrtcFuncNames.getUserMedia, e, null); }, /** * Notifies CallStats that peer connection failed to create offer. * * @param {Error} e error to send + * @param {RTCPeerConnection} pc connection on which failure occured. */ - sendCreateOfferFailed: function (e) { - if(!callStats) { - return; - } - callStats.reportError(this.peerconnection, this.confID, - callStats.webRTCFunctions.createOffer, e); + sendCreateOfferFailed: function (e, pc) { + this._reportError(wrtcFuncNames.createOffer, e, pc); }, /** * Notifies CallStats that peer connection failed to create answer. * * @param {Error} e error to send + * @param {RTCPeerConnection} pc connection on which failure occured. */ - sendCreateAnswerFailed: function (e) { - if(!callStats) { - return; - } - callStats.reportError(this.peerconnection, this.confID, - callStats.webRTCFunctions.createAnswer, e); + sendCreateAnswerFailed: function (e, pc) { + this._reportError(wrtcFuncNames.createAnswer, e, pc); }, /** * Notifies CallStats that peer connection failed to set local description. * * @param {Error} e error to send + * @param {RTCPeerConnection} pc connection on which failure occured. */ - sendSetLocalDescFailed: function (e) { - if(!callStats) { - return; - } - callStats.reportError(this.peerconnection, this.confID, - callStats.webRTCFunctions.setLocalDescription, e); + sendSetLocalDescFailed: function (e, pc) { + this._reportError(wrtcFuncNames.setLocalDescription, e, pc); }, /** * Notifies CallStats that peer connection failed to set remote description. * * @param {Error} e error to send + * @param {RTCPeerConnection} pc connection on which failure occured. */ - sendSetRemoteDescFailed: function (e) { - if(!callStats) { - return; - } - callStats.reportError( - this.peerconnection, this.confID, - callStats.webRTCFunctions.setRemoteDescription, e); + sendSetRemoteDescFailed: function (e, pc) { + this._reportError(wrtcFuncNames.setRemoteDescription, e, pc); }, /** * Notifies CallStats that peer connection failed to add ICE candidate. * * @param {Error} e error to send + * @param {RTCPeerConnection} pc connection on which failure occured. */ - sendAddIceCandidateFailed: function (e) { - if(!callStats) { - return; - } - callStats.reportError(this.peerconnection, this.confID, - callStats.webRTCFunctions.addIceCandidate, e); + sendAddIceCandidateFailed: function (e, pc) { + this._reportError(wrtcFuncNames.addIceCandidate, e, pc); } }; module.exports = CallStats; diff --git a/modules/statistics/statistics.js b/modules/statistics/statistics.js index 91908f0de..9f63b0786 100644 --- a/modules/statistics/statistics.js +++ b/modules/statistics/statistics.js @@ -113,25 +113,30 @@ var statistics = { APP.RTC.addListener(RTCEvents.GET_USER_MEDIA_FAILED, function (e) { CallStats.sendGetUserMediaFailed(e); }); - APP.xmpp.addListener(RTCEvents.CREATE_OFFER_FAILED, function (e) { - CallStats.sendCreateOfferFailed(e); + APP.xmpp.addListener(RTCEvents.CREATE_OFFER_FAILED, function (e, pc) { + CallStats.sendCreateOfferFailed(e, pc); }); - APP.xmpp.addListener(RTCEvents.CREATE_ANSWER_FAILED, function (e) { - CallStats.sendCreateAnswerFailed(e); + APP.xmpp.addListener(RTCEvents.CREATE_ANSWER_FAILED, function (e, pc) { + CallStats.sendCreateAnswerFailed(e, pc); }); APP.xmpp.addListener( RTCEvents.SET_LOCAL_DESCRIPTION_FAILED, - function (e) { - CallStats.sendSetLocalDescFailed(e); - }); + function (e, pc) { + CallStats.sendSetLocalDescFailed(e, pc); + } + ); APP.xmpp.addListener( RTCEvents.SET_REMOTE_DESCRIPTION_FAILED, - function (e) { - CallStats.sendSetRemoteDescFailed(e); - }); - APP.xmpp.addListener(RTCEvents.ADD_ICE_CANDIDATE_FAILED, function (e) { - CallStats.sendAddIceCandidateFailed(e); - }); + function (e, pc) { + CallStats.sendSetRemoteDescFailed(e, pc); + } + ); + APP.xmpp.addListener( + RTCEvents.ADD_ICE_CANDIDATE_FAILED, + function (e, pc) { + CallStats.sendAddIceCandidateFailed(e, pc); + } + ); } }; diff --git a/modules/xmpp/JingleSessionPC.js b/modules/xmpp/JingleSessionPC.js index 9f167d9af..6500e6186 100644 --- a/modules/xmpp/JingleSessionPC.js +++ b/modules/xmpp/JingleSessionPC.js @@ -720,7 +720,7 @@ JingleSessionPC.prototype.addIceCandidate = function (elem) { self.peerconnection.addIceCandidate(candidate); } catch (e) { console.error('addIceCandidate failed', e.toString(), line); - self.eventEmitter.emit(RTCEvents.ADD_ICE_CANDIDATE_FAILED, err); + self.eventEmitter.emit(RTCEvents.ADD_ICE_CANDIDATE_FAILED, err, self.peerconnection); } }); }); diff --git a/modules/xmpp/TraceablePeerConnection.js b/modules/xmpp/TraceablePeerConnection.js index 4e05a2811..eb8771387 100644 --- a/modules/xmpp/TraceablePeerConnection.js +++ b/modules/xmpp/TraceablePeerConnection.js @@ -293,7 +293,7 @@ TraceablePeerConnection.prototype.setLocalDescription }, function (err) { self.trace('setLocalDescriptionOnFailure', err); - self.eventEmitter.emit(RTCEvents.SET_LOCAL_DESCRIPTION_FAILED, err); + self.eventEmitter.emit(RTCEvents.SET_LOCAL_DESCRIPTION_FAILED, err, self.peerconnection); failureCallback(err); } ); @@ -329,7 +329,7 @@ TraceablePeerConnection.prototype.setRemoteDescription }, function (err) { self.trace('setRemoteDescriptionOnFailure', err); - self.eventEmitter.emit(RTCEvents.SET_REMOTE_DESCRIPTION_FAILED, err); + self.eventEmitter.emit(RTCEvents.SET_REMOTE_DESCRIPTION_FAILED, err, self.peerconnection); failureCallback(err); } ); @@ -375,7 +375,7 @@ TraceablePeerConnection.prototype.createOffer }, function(err) { self.trace('createOfferOnFailure', err); - self.eventEmitter.emit(RTCEvents.CREATE_OFFER_FAILED, err); + self.eventEmitter.emit(RTCEvents.CREATE_OFFER_FAILED, err, self.peerconnection); failureCallback(err); }, constraints @@ -406,7 +406,7 @@ TraceablePeerConnection.prototype.createAnswer }, function(err) { self.trace('createAnswerOnFailure', err); - self.eventEmitter.emit(RTCEvents.CREATE_ANSWER_FAILED, err); + self.eventEmitter.emit(RTCEvents.CREATE_ANSWER_FAILED, err, self.peerconnection); failureCallback(err); }, constraints