Преглед на файлове

Don't keep on refetching roster if the service is unavailable

`sendIQ` now takes a flag to turn of rejection of the promise and to
resolve on error IQs instead.
JC Brand преди 6 години
родител
ревизия
8bd72eed72
променени са 3 файла, в които са добавени 33 реда и са изтрити 20 реда
  1. 14 5
      src/headless/converse-core.js
  2. 12 15
      src/headless/converse-roster.js
  3. 7 0
      src/headless/utils/core.js

+ 14 - 5
src/headless/converse-core.js

@@ -1837,14 +1837,23 @@ _converse.api = {
     /**
      * Send an IQ stanza and receive a promise
      * @method _converse.api.sendIQ
+     * @param { XMLElement } stanza
+     * @param { Integer } timeout
+     * @param { Boolean } reject - Whether an error IQ should cause the promise
+     *  to be rejected. If `false`, the promise will resolve instead of being rejected.
      * @returns {Promise} A promise which resolves when we receive a `result` stanza
      * or is rejected when we receive an `error` stanza.
      */
-    sendIQ (stanza, timeout) {
-        return new Promise((resolve, reject) => {
-            _converse.connection.sendIQ(stanza, resolve, reject, timeout || _converse.IQ_TIMEOUT);
-            _converse.api.trigger('send', stanza);
-        });
+    sendIQ (stanza, timeout, reject=true) {
+        timeout = timeout || _converse.IQ_TIMEOUT;
+        let promise;
+        if (reject) {
+            promise = new Promise((resolve, reject) => _converse.connection.sendIQ(stanza, resolve, reject, timeout));
+        } else {
+            promise = new Promise((resolve, reject) => _converse.connection.sendIQ(stanza, resolve, resolve, timeout));
+        }
+        _converse.api.trigger('send', stanza);
+        return promise;
     }
 };
 

+ 12 - 15
src/headless/converse-roster.js

@@ -653,21 +653,18 @@ converse.plugins.add('converse-roster', {
                 if (this.rosterVersioningSupported()) {
                     stanza.attrs({'ver': this.data.get('version')});
                 }
-                let iq;
-                try {
-                    iq = await _converse.api.sendIQ(stanza);
-                } catch (e) {
-                    _converse.log(e, Strophe.LogLevel.ERROR);
-                    return _converse.log(
-                        "Error while trying to fetch roster from the server",
-                        Strophe.LogLevel.ERROR
-                    );
-                }
-                const query = sizzle(`query[xmlns="${Strophe.NS.ROSTER}"]`, iq).pop();
-                if (query) {
-                    const items = sizzle(`item`, query);
-                    items.forEach(item => this.updateContact(item));
-                    this.data.save('version', query.getAttribute('ver'));
+                const iq = await _converse.api.sendIQ(stanza, null, false);
+                if (iq.getAttribute('type') !== 'error') {
+                    const query = sizzle(`query[xmlns="${Strophe.NS.ROSTER}"]`, iq).pop();
+                    if (query) {
+                        const items = sizzle(`item`, query);
+                        items.forEach(item => this.updateContact(item));
+                        this.data.save('version', query.getAttribute('ver'));
+                    }
+                } else if (!u.isServiceUnavailableError(iq)) {
+                    // Some unknown error happened, so we will try to fetch again if the page reloads.
+                    _converse.log(iq, Strophe.LogLevel.ERROR);
+                    return _converse.log("Error while trying to fetch roster from the server", Strophe.LogLevel.ERROR);
                 }
                 _converse.session.save('roster_fetched', true);
                 /**

+ 7 - 0
src/headless/utils/core.js

@@ -156,6 +156,13 @@ u.isHeadlineMessage = function (_converse, message) {
     return false;
 };
 
+u.isServiceUnavailableError = function (stanza) {
+    if (!_.isElement(stanza)) {
+        return false;
+    }
+    return sizzle(`error[type="cancel"] service-unavailable[xmlns="${Strophe.NS.STANZAS}"]`, stanza).length > 0;
+}
+
 u.merge = function merge (first, second) {
     /* Merge the second object into the first one.
      */