[MERGE] Add ErrorFromSmartServer exception, and raise it from read_response_tuple for all protocol versions (protocol v3 patch 5/7)

John Arbash Meinel john at arbash-meinel.com
Mon Apr 28 23:00:58 BST 2008


John Arbash Meinel has voted tweak.
Status is now: Conditionally approved
Comment:
Is peaking at "error_tuple[]" the right way to do it?
You do stuff like:

if e.error_tuple = (some, value):

and

if e.error_tuple[0] == 'xxxx':

I would worry if error_tuple is empty, then the latter would raise an 
IndexError instead of the original error. I would be happier if the 
errors were more standardized, so you would have:
e.error_type or some other member that represents the first entry in 
error_tuple.

Otherwise, I think I would use slices instead of direct indexes. So 
something like:

if e.error_tuple[:1] == ('xxxxx',):

That way if the tuple is empty, you get () != ('xxxx',) rather than an 
index error. (Of course, error_tuple can't be None, etc.


+        try:
+            response = self._client.call_expecting_body(
+                'Repository.get_revision_graph', path, revision_id)
+        except errors.ErrorFromSmartServer, err:
+            if err.error_tuple[0] == 'nosuchrevision':
+                raise NoSuchRevision(self, revision_id)
+        if response[0][0] != 'ok':

^-- I think there is a latent bug here. If an error is raised which is 
not
"NoSuchRevision" then it will fall through. But 'response' isn't set 
either,
because an exception was raised. I think you need:

+            if err.error_tuple[0] == 'nosuchrevision':
+                raise NoSuchRevision(self, revision_id)
+            raise
+        if response[0][0] != 'ok':


+        except errors.ErrorFromSmartServer, err:
+            if err.error_tuple[0] == 'LockContention':
+                raise errors.LockContention('(remote lock)')
+            elif err.error_tuple[0] == 'UnlockableTransport':
+                raise 
errors.UnlockableTransport(self.bzrdir.root_transport)
+            elif err.error_tuple[0] == 'LockFailed':
+                raise errors.LockFailed(err.error_tuple[1], 
err.error_tuple[2])

^- More of a side question. why is the other error "nobranch" but these 
errors
are all 'LockContention' (CamelCase). Seems inconsistent. Unless the 
first is
a plain response and the others are exceptions?

+            if self._requested_parents is not None and len(ancestry) != 
0:
+                self._requested_parents.update(present_keys)
+                mutter('Current RemoteRepository graph hit rate: %d%%',
+                    100.0 * len(self._requested_parents) / 
len(ancestry))

^- Since we are here, *I* would really like it if this printed the 
actual
counts for _requested_parents and ancestry.


Again here:
@@ -1503,10 +1518,11 @@
              self._ensure_real()
              self._clear_cached_state()
              return self._real_branch.set_last_revision_info(revno, 
revision_id)
+        except errors.ErrorFromSmartServer, err:
+            if err.error_tuple[0] == 'NoSuchRevision':
+                raise NoSuchRevision(self, err.error_tuple[1])
          if response == ('ok',):
              self._clear_cached_state()
-        elif response[0] == 'NoSuchRevision':
-            raise NoSuchRevision(self, response[1])
          else:
              raise errors.UnexpectedSmartServerResponse(response)

I think you need the plain 'raise' section. Should we have explicit 
tests for
these?



+        client.add_success_response_with_body('', 'ok')

^- Why does 'add_success_...' need to supply 'ok'. Do some of them 
return
something other than 'ok' for success?

I guess later on you have:
+        repo, client = self.setup_fake_client_and_repository('path')
+        client.add_success_response('something unexpected!')


For details, see: 
http://bundlebuggy.aaronbentley.com/request/%3C20080423231923.GI9546%40steerpike.home.puzzling.org%3E



More information about the bazaar mailing list