diff sat/plugins/plugin_xep_0045.py @ 3080:16925f494820

plugin XEP-0045: don't fail on `item-not-found` with MAM: Some servers don't store permanently the whole history of MUC with MAM. As a result, an "item-not-found" stanza error can be received when message id used as reference doesn't exist anymore on the server. When this case happens, the history is retrieved in the same way as for a newly joined room (i.e. last 50 messages are requested).
author Goffi <goffi@goffi.org>
date Thu, 05 Dec 2019 23:05:16 +0100
parents 730bbed77a89
children 13be04a70e2f
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0045.py	Thu Dec 05 22:58:06 2019 +0100
+++ b/sat/plugins/plugin_xep_0045.py	Thu Dec 05 23:05:16 2019 +0100
@@ -20,9 +20,9 @@
 from sat.core.i18n import _, D_
 from sat.core.constants import Const as C
 from sat.core.log import getLogger
-log = getLogger(__name__)
 from twisted.internet import defer
 from twisted.words.protocols.jabber import jid
+from twisted.words.protocols.jabber import error as xmpp_error
 from twisted.python import failure
 
 from sat.core import exceptions
@@ -41,6 +41,9 @@
 from wokkel import mam
 
 
+log = getLogger(__name__)
+
+
 PLUGIN_INFO = {
     C.PI_NAME: "XEP-0045 Plugin",
     C.PI_IMPORT_NAME: "XEP-0045",
@@ -979,8 +982,22 @@
         complete = False
         count = 0
         while not complete:
-            mam_data = yield self._mam.getArchives(client, mam_req,
-                                                   service=room_jid)
+            try:
+                mam_data = yield self._mam.getArchives(client, mam_req,
+                                                       service=room_jid)
+            except xmpp_error.StanzaError as e:
+                if last_mess and e.condition == 'item-not-found':
+                    log.info(
+                        f"requested item (with id {stanza_id!r}) can't be found in "
+                        f"history of {room_jid}, history has probably been purged on "
+                        f"server.")
+                    # we get last items like for a new room
+                    rsm_req = rsm.RSMRequest(max_=50, before='')
+                    mam_req = mam.MAMRequest(rsm_=rsm_req)
+                    no_loop=True
+                    continue
+                else:
+                    raise e
             elt_list, rsm_response, mam_response = mam_data
             complete = True if no_loop else mam_response["complete"]
             # we update MAM request for next iteration