dispatch: print traceback in scmutil.callcatch() if --traceback specified
authorYuya Nishihara <yuya@tcha.org>
Sat, 15 Apr 2017 13:02:34 +0900
changeset 32041 38963a53ab0d
parent 32040 0fb78cb90ca7
child 32042 8f8ad0139b8b
dispatch: print traceback in scmutil.callcatch() if --traceback specified Otherwise, traceback wouldn't be printed for a known exception occurred in worker processes.
mercurial/dispatch.py
mercurial/scmutil.py
tests/test-worker.t
--- a/mercurial/dispatch.py	Sat Apr 15 12:58:06 2017 +0900
+++ b/mercurial/dispatch.py	Sat Apr 15 13:02:34 2017 +0900
@@ -255,7 +255,6 @@
             if '--debugger' in req.args:
                 traceback.print_exc()
                 debugmortem[debugger](sys.exc_info()[2])
-            ui.traceback()
             raise
 
     return _callcatch(ui, _runcatchfunc)
--- a/mercurial/scmutil.py	Sat Apr 15 12:58:06 2017 +0900
+++ b/mercurial/scmutil.py	Sat Apr 15 13:02:34 2017 +0900
@@ -142,7 +142,11 @@
     and return an exit code accordingly. does not handle all exceptions.
     """
     try:
-        return func()
+        try:
+            return func()
+        except: # re-raises
+            ui.traceback()
+            raise
     # Global exception handling, alphabetically
     # Mercurial-specific first, followed by built-in and library exceptions
     except error.LockHeld as inst:
--- a/tests/test-worker.t	Sat Apr 15 12:58:06 2017 +0900
+++ b/tests/test-worker.t	Sat Apr 15 13:02:34 2017 +0900
@@ -4,20 +4,31 @@
   > from __future__ import absolute_import, print_function
   > from mercurial import (
   >     cmdutil,
+  >     error,
   >     ui as uimod,
   >     worker,
   > )
+  > def abort(ui, args):
+  >     if args[0] == 0:
+  >         # by first worker for test stability
+  >         raise error.Abort('known exception')
+  >     return runme(ui, [])
   > def runme(ui, args):
   >     for arg in args:
   >         ui.status('run\n')
   >         yield 1, arg
+  > functable = {
+  >     'abort': abort,
+  >     'runme': runme,
+  > }
   > cmdtable = {}
   > command = cmdutil.command(cmdtable)
-  > @command('test', [], 'hg test [COST]')
-  > def t(ui, repo, cost=1.0):
+  > @command('test', [], 'hg test [COST] [FUNC]')
+  > def t(ui, repo, cost=1.0, func='runme'):
   >     cost = float(cost)
+  >     func = functable[func]
   >     ui.status('start\n')
-  >     runs = worker.worker(ui, cost, runme, (ui,), range(8))
+  >     runs = worker.worker(ui, cost, func, (ui,), range(8))
   >     for n, i in runs:
   >         pass
   >     ui.status('done\n')
@@ -52,3 +63,15 @@
   run
   run
   done
+
+Known exception should be caught, but printed if --traceback is enabled
+
+  $ hg --config "extensions.t=$abspath" --config 'worker.numcpus=2' \
+  > test 100000.0 abort
+  start
+  abort: known exception
+  done
+
+  $ hg --config "extensions.t=$abspath" --config 'worker.numcpus=2' \
+  > test 100000.0 abort --traceback 2>&1 | grep '^Traceback'
+  Traceback (most recent call last):