@@ -167,17 +167,31 @@ def load(ui, name, path):
def _runuisetup(name, ui):
uisetup = getattr(_extensions[name], 'uisetup', None)
if uisetup:
- uisetup(ui)
+ try:
+ uisetup(ui)
+ except Exception as inst:
+ ui.traceback()
+ msg = _forbytes(inst)
+ ui.warn(_("*** failed to set up extension %s: %s\n") % (name, msg))
+ return False
+ return True
def _runextsetup(name, ui):
extsetup = getattr(_extensions[name], 'extsetup', None)
if extsetup:
try:
- extsetup(ui)
- except TypeError:
- if inspect.getargspec(extsetup).args:
- raise
- extsetup() # old extsetup with no ui argument
+ try:
+ extsetup(ui)
+ except TypeError:
+ if inspect.getargspec(extsetup).args:
+ raise
+ extsetup() # old extsetup with no ui argument
+ except Exception as inst:
+ ui.traceback()
+ msg = _forbytes(inst)
+ ui.warn(_("*** failed to set up extension %s: %s\n") % (name, msg))
+ return False
+ return True
def loadall(ui, whitelist=None):
result = ui.configitems("extensions")
@@ -203,11 +217,19 @@ def loadall(ui, whitelist=None):
ui.warn(_("*** (%s)\n") % inst.hint)
ui.traceback()
+ broken = set()
for name in _order[newindex:]:
- _runuisetup(name, ui)
+ if not _runuisetup(name, ui):
+ broken.add(name)
for name in _order[newindex:]:
- _runextsetup(name, ui)
+ if name in broken:
+ continue
+ if not _runextsetup(name, ui):
+ broken.add(name)
+
+ for name in broken:
+ _extensions[name] = None
# Call aftercallbacks that were never met.
for shortname in _aftercallbacks:
@@ -215,7 +237,7 @@ def loadall(ui, whitelist=None):
continue
for fn in _aftercallbacks[shortname]:
- fn(loaded=False)
+ fn(loaded=_extensions[shortname] is not None)
# loadall() is called multiple times and lingering _aftercallbacks
# entries could result in double execution. See issue4646.
@@ -1625,9 +1625,35 @@ Make sure a broken uisetup doesn't globa
> baduisetup = $PWD/baduisetup.py
> EOF
-Broken: an extension that triggers the import of bdiff during uisetup
-can't be easily debugged:
+Even though the extension fails during uisetup, hg is still basically usable:
$ hg version
- abort: No module named bdiff!
- (did you forget to compile extensions?)
- [255]
+ *** failed to set up extension baduisetup: No module named bdiff
+ Mercurial Distributed SCM (version *) (glob)
+ (see https://mercurial-scm.org for more information)
+
+ Copyright (C) 2005-2017 Matt Mackall and others
+ This is free software; see the source for copying conditions. There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ $ hg version --traceback
+ Traceback (most recent call last):
+ File "*/mercurial/extensions.py", line *, in _runuisetup (glob)
+ uisetup(ui)
+ File "$TESTTMP/baduisetup.py", line 10, in uisetup
+ extensions.wrapfunction(bdiff, 'blocks', blockswrapper)
+ File "*/mercurial/extensions.py", line *, in wrapfunction (glob)
+ origfn = getattr(container, funcname)
+ File "*/hgdemandimport/demandimportpy2.py", line *, in __getattr__ (glob)
+ self._load()
+ File "*/hgdemandimport/demandimportpy2.py", line *, in _load (glob)
+ mod = _hgextimport(_import, head, globals, locals, None, level)
+ File "*/hgdemandimport/demandimportpy2.py", line *, in _hgextimport (glob)
+ return importfunc(name, globals, *args, **kwargs)
+ ImportError: No module named bdiff
+ *** failed to set up extension baduisetup: No module named bdiff
+ Mercurial Distributed SCM (version *) (glob)
+ (see https://mercurial-scm.org for more information)
+
+ Copyright (C) 2005-2017 Matt Mackall and others
+ This is free software; see the source for copying conditions. There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@@ -161,7 +161,8 @@
> EOF
$ echo 'this should fail' > file
$ hg commit -Aqm 'add file'
- abort: cannot register multiple processors on flag '0x8'.
+ *** failed to set up extension duplicate: cannot register multiple processors on flag '0x8'.
+ abort: missing processor for flag '0x1'!
[255]
$ cd ..