D4926: wireprotov2: raise exception in objects() if future has been resolved

indygreg (Gregory Szorc) phabricator at mercurial-scm.org
Wed Oct 10 10:58:18 EDT 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rHGed4ebbb98ca0: wireprotov2: raise exception in objects() if future has been resolved (authored by indygreg, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D4926?vs=11765&id=11790

REVISION DETAIL
  https://phab.mercurial-scm.org/D4926

AFFECTED FILES
  mercurial/wireprotov2peer.py

CHANGE DETAILS

diff --git a/mercurial/wireprotov2peer.py b/mercurial/wireprotov2peer.py
--- a/mercurial/wireprotov2peer.py
+++ b/mercurial/wireprotov2peer.py
@@ -135,6 +135,7 @@
         self._serviceable = threading.Event()
 
         self._pendingevents = []
+        self._pendingerror = None
         self._decoder = cborutil.bufferingdecoder()
         self._seeninitial = False
         self._redirect = None
@@ -169,6 +170,12 @@
 
             self._serviceable.set()
 
+    def _onerror(self, e):
+        self._pendingerror = e
+
+        with self._lock:
+            self._serviceable.set()
+
     def _handleinitial(self, o):
         self._seeninitial = True
         if o[b'status'] == b'ok':
@@ -212,6 +219,9 @@
             # our state.
             self._serviceable.wait(1.0)
 
+            if self._pendingerror:
+                raise self._pendingerror
+
             with self._lock:
                 self._serviceable.clear()
 
@@ -342,9 +352,18 @@
             try:
                 self._processresponsedata(frame, meta, response)
             except BaseException as e:
-                self._futures[frame.requestid].set_exception(e)
-                del self._futures[frame.requestid]
-                response._oninputcomplete()
+                # If an exception occurs before the future is resolved,
+                # fail the future. Otherwise, we stuff the exception on
+                # the response object so it can be raised during objects()
+                # iteration. If nothing is consuming objects(), we could
+                # silently swallow this exception. That's a risk we'll have to
+                # take.
+                if frame.requestid in self._futures:
+                    self._futures[frame.requestid].set_exception(e)
+                    del self._futures[frame.requestid]
+                    response._oninputcomplete()
+                else:
+                    response._onerror(e)
         else:
             raise error.ProgrammingError(
                 'unhandled action from clientreactor: %s' % action)



To: indygreg, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list