From e4bac8c1296da7b32bfeee4b1b324dc4ff1c0429 Mon Sep 17 00:00:00 2001 From: Nicolas Bayet Date: Thu, 31 Aug 2023 14:12:19 +0200 Subject: [PATCH] [FIX] web_editor: prevent creation of RTCPeerConnection when offline Before this commit, when the browser was offline and when an attempt to make a RTCPeerConnection was made, a traceback was raised by firefox: > InvalidStateError: Can't create RTCPeerConnections when the network is > down This commit prevents the creation of the RTCPeerConnection when the browser is offline. task-3186872 closes odoo/odoo#134236 X-original-commit: 8f9a3e1ebd05d9df8ec0d82b93967f1a62f879c4 Signed-off-by: David Monjoie (dmo) --- .../static/src/js/wysiwyg/PeerToPeer.js | 36 +++++++++++-------- .../static/src/js/wysiwyg/wysiwyg.js | 2 +- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/addons/web_editor/static/src/js/wysiwyg/PeerToPeer.js b/addons/web_editor/static/src/js/wysiwyg/PeerToPeer.js index bf76695b9c1..36072e7a054 100644 --- a/addons/web_editor/static/src/js/wysiwyg/PeerToPeer.js +++ b/addons/web_editor/static/src/js/wysiwyg/PeerToPeer.js @@ -84,7 +84,7 @@ const baseNotificationMethods = { 'An offer has been received for a non-existent peer connection - client: ' + notification.fromClientId, ); - console.trace(pc.connectionState); + console.trace(pc && pc.connectionState); console.groupEnd(); } return; @@ -181,8 +181,8 @@ export class PeerToPeer { return Object.entries(this.clientsInfos) .filter( ([id, infos]) => - infos.peerConnection.iceConnectionState === 'connected' && - infos.dataChannel.readyState === 'open', + infos.peerConnection && infos.peerConnection.iceConnectionState === 'connected' && + infos.dataChannel && infos.dataChannel.readyState === 'open', ) .map(([id]) => id); } @@ -194,8 +194,8 @@ export class PeerToPeer { if (!clientInfos) return; clearTimeout(clientInfos.fallbackTimeout); clearTimeout(clientInfos.zombieTimeout); - clientInfos.dataChannel.close(); - clientInfos.peerConnection.close(); + clientInfos.dataChannel && clientInfos.dataChannel.close(); + clientInfos.peerConnection && clientInfos.peerConnection.close(); delete this.clientsInfos[clientId]; } @@ -381,6 +381,10 @@ export class PeerToPeer { iceCandidateBuffer: [], backoffFactor: 0, }; + + if (!navigator.onLine) { + return this.clientsInfos[clientId]; + } const pc = new RTCPeerConnection(this.options.peerConnectionConfig); if (makeOffer) { @@ -425,10 +429,12 @@ export class PeerToPeer { this.removeClient(clientId); break; case 'disconnected': - await this._recoverConnection(clientId, { - delay: 3000, - reason: 'ice connection disconnected', - }); + if (navigator.onLine) { + await this._recoverConnection(clientId, { + delay: 3000, + reason: 'ice connection disconnected', + }); + } break; case 'connected': this.clientsInfos[clientId].backoffFactor = 0; @@ -445,10 +451,12 @@ export class PeerToPeer { this.removeClient(clientId); break; case 'disconnected': - await this._recoverConnection(clientId, { - delay: 3000, - reason: 'connection disconnected', - }); + if (navigator.onLine) { + await this._recoverConnection(clientId, { + delay: 3000, + reason: 'connection disconnected', + }); + } break; case 'connected': case 'completed': @@ -618,7 +626,7 @@ export class PeerToPeer { // If there is no connection after 10 seconds, terminate. clientInfos.zombieTimeout = setTimeout(() => { - if (clientInfos && clientInfos.dataChannel.readyState !== 'open') { + if (clientInfos && clientInfos.dataChannel && clientInfos.dataChannel.readyState !== 'open') { if (debugShowLog) console.log(`%c KILL ZOMBIE ${clientId}`, 'background: red;'); this.removeClient(clientId); } else { diff --git a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js index ab7c6d0e51f..3dc9d3ad648 100644 --- a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js +++ b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js @@ -829,7 +829,7 @@ export class Wysiwyg extends Component { const clientsInfos = Object.values(this.ptp.clientsInfos); const couldBeDisconnected = Boolean(clientsInfos.length) && - clientsInfos.every((x) => PTP_CLIENT_DISCONNECTED_STATES.includes(x.peerConnection.connectionState)); + clientsInfos.every((x) => PTP_CLIENT_DISCONNECTED_STATES.includes(x.peerConnection && x.peerConnection.connectionState)); if (couldBeDisconnected) { this._offlineTimeout = setTimeout(() => {