hook: don't crash on syntax errors in python hooks
authorSiddharth Agarwal <sid0@fb.com>
Fri, 12 Feb 2016 14:50:10 -0800
changeset 28109 b892e424f88c
parent 28108 2a71d9483199
child 28110 2b41f8655bbc
hook: don't crash on syntax errors in python hooks We had some real-world cases where syntax errors in Python hooks would crash the whole process and leave it in an indeterminate state. Handle those better.
mercurial/hook.py
tests/test-hook.t
--- a/mercurial/hook.py	Fri Feb 12 11:44:35 2016 -0800
+++ b/mercurial/hook.py	Fri Feb 12 14:50:10 2016 -0800
@@ -49,12 +49,12 @@
         with demandimport.deactivated():
             try:
                 obj = __import__(modname)
-            except ImportError:
+            except (ImportError, SyntaxError):
                 e1 = sys.exc_info()
                 try:
                     # extensions are loaded with hgext_ prefix
                     obj = __import__("hgext_%s" % modname)
-                except ImportError:
+                except (ImportError, SyntaxError):
                     e2 = sys.exc_info()
                     if ui.tracebackflag:
                         ui.warn(_('exception from first failed import '
--- a/tests/test-hook.t	Fri Feb 12 11:44:35 2016 -0800
+++ b/tests/test-hook.t	Fri Feb 12 14:50:10 2016 -0800
@@ -436,6 +436,10 @@
   >     unreachable = 1
   > EOF
 
+  $ cat > syntaxerror.py << EOF
+  > (foo
+  > EOF
+
 test python hooks
 
 #if windows
@@ -518,6 +522,30 @@
   [255]
 
   $ echo '[hooks]' > ../a/.hg/hgrc
+  $ echo 'preoutgoing.syntaxerror = python:syntaxerror.syntaxerror' >> ../a/.hg/hgrc
+  $ hg pull ../a
+  pulling from ../a
+  searching for changes
+  abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
+  (run with --traceback for stack trace)
+  [255]
+
+  $ hg pull ../a --traceback 2>&1 | egrep -v '^( +File|    [_a-zA-Z*(])'
+  pulling from ../a
+  searching for changes
+  exception from first failed import attempt:
+  Traceback (most recent call last):
+      
+      ^
+  SyntaxError: invalid syntax
+  exception from second failed import attempt:
+  Traceback (most recent call last):
+  ImportError: No module named hgext_syntaxerror
+  Traceback (most recent call last):
+  HookLoadError: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
+  abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
+
+  $ echo '[hooks]' > ../a/.hg/hgrc
   $ echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
   $ hg pull ../a
   pulling from ../a