comparison mercurial/dispatch.py @ 28520:84cc72c5771e

dispatch: catch KeyboardInterrupt more broadly Because _runcatch() can run long operations in its exception handler, it wasn't enough to catch KeyboardInterrupt at the same level. For example, "hg unknown" will load all extension modules, so we could easily make it crashed by Ctrl-C.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 27 Dec 2015 13:38:46 +0900
parents 491eabd0df79
children 293adbaa14a7
comparison
equal deleted inserted replaced
28519:518a5030acba 28520:84cc72c5771e
118 msg = ' '.join(' ' in a and repr(a) or a for a in req.args) 118 msg = ' '.join(' ' in a and repr(a) or a for a in req.args)
119 starttime = time.time() 119 starttime = time.time()
120 ret = None 120 ret = None
121 try: 121 try:
122 ret = _runcatch(req) 122 ret = _runcatch(req)
123 return ret 123 except KeyboardInterrupt:
124 try:
125 req.ui.warn(_("interrupted!\n"))
126 except IOError as inst:
127 if inst.errno != errno.EPIPE:
128 raise
129 ret = -1
124 finally: 130 finally:
125 duration = time.time() - starttime 131 duration = time.time() - starttime
126 req.ui.log("commandfinish", "%s exited %s after %0.2f seconds\n", 132 req.ui.log("commandfinish", "%s exited %s after %0.2f seconds\n",
127 msg, ret or 0, duration) 133 msg, ret or 0, duration)
134 return ret
128 135
129 def _runcatch(req): 136 def _runcatch(req):
130 def catchterm(*args): 137 def catchterm(*args):
131 raise error.SignalInterrupt 138 raise error.SignalInterrupt
132 139
311 if getattr(inst, "filename", None) is not None: 318 if getattr(inst, "filename", None) is not None:
312 ui.warn(_("abort: %s: '%s'\n") % (inst.strerror, inst.filename)) 319 ui.warn(_("abort: %s: '%s'\n") % (inst.strerror, inst.filename))
313 else: 320 else:
314 ui.warn(_("abort: %s\n") % inst.strerror) 321 ui.warn(_("abort: %s\n") % inst.strerror)
315 except KeyboardInterrupt: 322 except KeyboardInterrupt:
316 try: 323 raise
317 ui.warn(_("interrupted!\n"))
318 except IOError as inst:
319 if inst.errno != errno.EPIPE:
320 raise
321 except MemoryError: 324 except MemoryError:
322 ui.warn(_("abort: out of memory\n")) 325 ui.warn(_("abort: out of memory\n"))
323 except SystemExit as inst: 326 except SystemExit as inst:
324 # Commands shouldn't sys.exit directly, but give a return code. 327 # Commands shouldn't sys.exit directly, but give a return code.
325 # Just in case catch this and and pass exit code to caller. 328 # Just in case catch this and and pass exit code to caller.