2016-08-04 92 views
0

处理Mercurial扩展中的错误的建议方法是什么?我们无法在线找到有关此方面的任何文档。如何处理Mercurial扩展中的错误

以下示例将在Windows外壳中打印Hello world并将errorlevel设置为1

@command('print-parents', [('','', None, '')], '') 
def printparents(ui, repo, node, **opts): 
    print "Hello world" 
    return True 

为什么errorlevel设置为1?我们预计它是0。在这种情况下,Python或Mercurial如何处理TrueFalse?更改为返回False产生errorlevel0

我们已经看到了一些raise error.Abort(..)的例子,但是这个输出非常冗长的调用堆栈并不是必需的。简单的文本消息和正确的errorlevel是需要的。

使用Windows 7和水银3.4.1

+0

为什么你的命令完全返回'True'? “@ command”的返回值被解释为退出代码,在Python中被解释为“True == 1”。 –

回答

0

@command功能,使用ui.warn()显示错误消息,然后返回一个整数值来设置退出代码:

if something_is_wrong: 
    ui.warn(_('Something is wrong, please correct this')) 
    return 1 

然而,使用raise mercurial.error.Abort()也不错,并且不会导致回溯,除非您将ui.traceback设置为True(默认为False)。提高Abort()通常会导致ui.warn('abort: ' + msg_from_exception)return -1组合(这会导致255退出代码):

$ cat demo.py 
from mercurial import cmdutil, error 

cmdtable = {} 
command = cmdutil.command(cmdtable) 

@command('demo1', [], '') 
def demo1(ui, repo, *args, **opts): 
    ui.warn('Error message written directly to ui.warn') 
    return 1 

@command('demo2', [], '') 
def demo2(ui, repo, *args, **opts): 
    raise error.Abort('Error message raised with Abort') 

$ hg --config extensions.demo=`pwd`/demo.py demo1 
Error message written directly to ui.warn 
$ echo $? 
1 
$ hg --config extensions.demo=`pwd`/demo.py demo2 
abort: Error message raised with Abort 
$? 
255 
$ hg --config extensions.demo=`pwd`/demo.py --config ui.traceback=true demo2 
Traceback (most recent call last): 
    File "/opt/facebook/hg/lib/python2.7/site-packages/mercurial/dispatch.py", line 204, in _runcatch 
    return _dispatch(req) 
    File "/opt/facebook/hg/lib/python2.7/site-packages/mercurial/dispatch.py", line 880, in _dispatch 
    cmdpats, cmdoptions) 
    File "/opt/facebook/hg/lib/python2.7/site-packages/mercurial/extensions.py", line 210, in closure 
    return func(*(args + a), **kw) 
    File "/opt/facebook/hg/lib/python2.7/site-packages/fastmanifest/cachemanager.py", line 318, in runcommandtrigger 
    result = orig(*args, **kwargs) 
    File "/opt/facebook/hg/lib/python2.7/site-packages/mercurial/extensions.py", line 210, in closure 
    return func(*(args + a), **kw) 
    File "/opt/facebook/hg/lib/python2.7/site-packages/fastmanifest/__init__.py", line 174, in _logonexit 
    r = orig(ui, repo, cmd, fullargs, *args) 
    File "/opt/facebook/hg/lib/python2.7/site-packages/mercurial/extensions.py", line 210, in closure 
    return func(*(args + a), **kw) 
    File "/opt/facebook/hg/lib/python2.7/site-packages/hgext/journal.py", line 79, in runcommand 
    return orig(lui, repo, cmd, fullargs, *args) 
    File "/opt/facebook/hg/lib/python2.7/site-packages/mercurial/dispatch.py", line 637, in runcommand 
    ret = _runcommand(ui, options, cmd, d) 
    File "/opt/facebook/hg/lib/python2.7/site-packages/mercurial/extensions.py", line 210, in closure 
    return func(*(args + a), **kw) 
    File "/opt/facebook/hg/lib/python2.7/site-packages/hgext/pager.py", line 160, in pagecmd 
    return orig(ui, options, cmd, cmdfunc) 
    File "/opt/facebook/hg/lib/python2.7/site-packages/mercurial/extensions.py", line 210, in closure 
    return func(*(args + a), **kw) 
    File "/opt/facebook/hg/lib/python2.7/site-packages/hgext/color.py", line 503, in colorcmd 
    return orig(ui_, opts, cmd, cmdfunc) 
    File "/opt/facebook/hg/lib/python2.7/site-packages/mercurial/dispatch.py", line 1010, in _runcommand 
    return checkargs() 
    File "/opt/facebook/hg/lib/python2.7/site-packages/mercurial/dispatch.py", line 971, in checkargs 
    return cmdfunc() 
    File "/opt/facebook/hg/lib/python2.7/site-packages/mercurial/dispatch.py", line 877, in <lambda> 
    d = lambda: util.checksignature(func)(ui, *args, **cmdoptions) 
    File "/opt/facebook/hg/lib/python2.7/site-packages/mercurial/util.py", line 1036, in check 
    return func(*args, **kwargs) 
    File "/tmp/demo/demo.py", line 13, in demo2 
    raise error.Abort('Error message raised with Abort') 
Abort: Error message raised with Abort 
abort: Error message raised with Abort 

注意,我必须明确地启用追踪!

在Python中,bool类型是int的子类,和True具有1一个值和False具有0的整数值。由于Mercurial预计@command函数会返回一个整数来设置退出代码(或退出代码为0的None),因此您通过返回True将退出代码设置为1

我通常会查看mercurial.commands模块和各种hgext扩展名,以了解其他人如何解决特定问题。该hg grep命令,例如,包含处理错误的例子:

try: 
    regexp = util.re.compile(pattern, reflags) 
except re.error as inst: 
    ui.warn(_("grep: invalid match pattern: %s\n") % inst) 
    return 1 

hg addremove代码引发error.Abort()

try: 
    sim = float(opts.get('similarity') or 100) 
except ValueError: 
    raise error.Abort(_('similarity must be a number')) 

我会使用error.Abort()的命令错误,并ui.warn()加上返回一个整数只有当你特别需要退出代码而不是255.

+0

非常好的描述,谢谢:-) – Lars