Patchwork [4,of,4] hook: don't crash on syntax errors in python hooks

login
register
mail settings
Submitter Siddharth Agarwal
Date Feb. 12, 2016, 10:53 p.m.
Message ID <d046c71f86718d41b9c5.1455317631@dev666.prn1.facebook.com>
Download mbox | patch
Permalink /patch/13165/
State Accepted
Headers show

Comments

Siddharth Agarwal - Feb. 12, 2016, 10:53 p.m.
# HG changeset patch
# User Siddharth Agarwal <sid0@fb.com>
# Date 1455317410 28800
#      Fri Feb 12 14:50:10 2016 -0800
# Node ID d046c71f86718d41b9c5e9f601ca0f0d87606239
# Parent  c9fcff42975be8331c4e10add62d3bca983d155e
# Available At http://42.netv6.net/sid0-wip/hg/
#              hg pull http://42.netv6.net/sid0-wip/hg/ -r d046c71f8671
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.
Pierre-Yves David - Feb. 13, 2016, 3:54 p.m.
On 02/12/2016 10:53 PM, Siddharth Agarwal wrote:
> # HG changeset patch
> # User Siddharth Agarwal <sid0@fb.com>
> # Date 1455317410 28800
> #      Fri Feb 12 14:50:10 2016 -0800
> # Node ID d046c71f86718d41b9c5e9f601ca0f0d87606239
> # Parent  c9fcff42975be8331c4e10add62d3bca983d155e
> # Available At http://42.netv6.net/sid0-wip/hg/
> #              hg pull http://42.netv6.net/sid0-wip/hg/ -r d046c71f8671
> hook: don't crash on syntax errors in python hooks

Pushed to the clowncopter. Thanks.

(thanks for the pull url)

Patch

diff --git a/mercurial/hook.py b/mercurial/hook.py
--- a/mercurial/hook.py
+++ b/mercurial/hook.py
@@ -49,12 +49,12 @@  def _pythonhook(ui, repo, name, hname, f
         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 '
diff --git a/tests/test-hook.t b/tests/test-hook.t
--- a/tests/test-hook.t
+++ b/tests/test-hook.t
@@ -436,6 +436,10 @@  preoutgoing hook can prevent outgoing ch
   >     unreachable = 1
   > EOF
 
+  $ cat > syntaxerror.py << EOF
+  > (foo
+  > EOF
+
 test python hooks
 
 #if windows
@@ -518,6 +522,30 @@  test python hooks
   [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