robustcheckout: refactor handlepullabort to handle multiple types (
bug 1317594); r?glob
Not all network-related failures raise error.Abort. In preparation
for handling other error types, teach the function to check the
exception type and rename it so it isn't limited to error.Abort.
MozReview-Commit-ID: 9v4HSfors0z
--- a/hgext/robustcheckout/__init__.py
+++ b/hgext/robustcheckout/__init__.py
@@ -245,30 +245,31 @@ def _docheckout(ui, url, dest, upstream,
jittermin = ui.configint('robustcheckout', 'retryjittermin', 1000)
jittermax = ui.configint('robustcheckout', 'retryjittermax', 5000)
backoff += float(random.randint(jittermin, jittermax)) / 1000.0
ui.warn('(waiting %.2fs before retry)\n' % backoff)
time.sleep(backoff)
networkattempts[0] += 1
- def handlepullabort(e):
- """Handle an error.Abort raised during a pull.
+ def handlepullerror(e):
+ """Handle an exception raised during a pull.
Returns True if caller should call ``callself()`` to retry.
"""
- if e.args[0] == _('repository is unrelated'):
- ui.warn('(repository is unrelated; deleting)\n')
- destvfs.rmtree(forcibly=True)
- return True
- elif e.args[0].startswith(_('stream ended unexpectedly')):
- ui.warn('%s\n' % e.args[0])
- # Will raise if failure limit reached.
- handlenetworkfailure()
- return True
+ if isinstance(e, error.Abort):
+ if e.args[0] == _('repository is unrelated'):
+ ui.warn('(repository is unrelated; deleting)\n')
+ destvfs.rmtree(forcibly=True)
+ return True
+ elif e.args[0].startswith(_('stream ended unexpectedly')):
+ ui.warn('%s\n' % e.args[0])
+ # Will raise if failure limit reached.
+ handlenetworkfailure()
+ return True
return False
created = False
if not destvfs.exists():
# Ensure parent directories of destination exist.
# Mercurial 3.8 removed ensuredirs and made makedirs race safe.
@@ -283,17 +284,17 @@ def _docheckout(ui, url, dest, upstream,
if upstream:
ui.write('(cloning from upstream repo %s)\n' % upstream)
cloneurl = upstream or url
try:
res = hg.clone(ui, {}, cloneurl, dest=dest, update=False,
shareopts={'pool': sharebase, 'mode': 'identity'})
except error.Abort as e:
- if handlepullabort(e):
+ if handlepullerror(e):
return callself()
raise
except error.RepoError as e:
return handlerepoerror(e)
except error.RevlogError as e:
ui.warn('(repo corruption: %s; deleting shared store)\n' % e.message)
deletesharedstore()
return callself()
@@ -342,17 +343,17 @@ def _docheckout(ui, url, dest, upstream,
if checkoutrevision in repo:
ui.warn('(revision already present locally; not pulling)\n')
else:
pullop = exchange.pull(repo, remote, heads=pullrevs)
if not pullop.rheads:
raise error.Abort('unable to pull requested revision')
except error.Abort as e:
- if handlepullabort(e):
+ if handlepullerror(e):
return callself()
raise
except error.RepoError as e:
return handlerepoerror(e)
except error.RevlogError as e:
ui.warn('(repo corruption: %s; deleting shared store)\n' % e.message)
deletesharedstore()
return callself()