diff mercurial/extensions.py @ 32724:ea1c2eb7abd3

extensions: catch uisetup and extsetup failures and don't let them break hg Otherwise users of the patience diff extension will be unable to run anything at all in hg 4.3 until they figure out what's broken.
author Augie Fackler <augie@google.com>
date Tue, 06 Jun 2017 10:09:48 -0400
parents de09138bf0f5
children 80a5d237a4ae
line wrap: on
line diff
--- a/mercurial/extensions.py	Tue Jun 06 10:03:16 2017 -0400
+++ b/mercurial/extensions.py	Tue Jun 06 10:09:48 2017 -0400
@@ -167,17 +167,31 @@
 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 @@
                 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: