2017-04-23 5 views
0

我在写一个简单的服务器程序。在新代码中,它们将是不可避免的拼写错误和其他错误,通常python解释器将打印ValueError/AttributeError跟踪并退出。回溯可以指向错误的确切位置。但是在扭曲的框架下,这些错误不会被打印出来。就像下面的例子:在MyFactory.announce如何让扭曲打印未处理的错误的确切位置

from twisted.internet import reactor, protocol, task 
#from twisted.internet.defer import setDebugging 
#setDebugging(True) 

class MyProtocol(protocol.Protocol): 
    def dataReceived(self, data): 
     try: 
      set_position(int(data)) 
     except ValueError: 
      pass 
    def connectionMade(self): 
     self.factory.clientConnectionMade(self) 
    def connectionLost(self, reason): 
     self.factory.clientConnectionLost(self) 

class MyFactory(protocol.Factory): 
    protocol = MyProtocol 
    def __init__(self): 
     self.clients = [] 
     self.lc = task.LoopingCall(self.announce) 
     self.lc.start(1) 

    def announce(self): 
     pos = A_GREAT_TYPO_HERE() 
     for client in self.clients: 
      client.transport.write("Posiiton is {0}\n".format(pos).encode('utf-8')) 

    def clientConnectionMade(self, client): 
     self.clients.append(client) 

    def clientConnectionLost(self, client): 
     self.clients.remove(client) 

def get_position(): 
    return position[0] 

def set_position(pos): 
    position[0] = pos 

def main(): 
    global position 
    position = [0] 
    myfactory = MyFactory() 
    reactor.listenTCP(5362, myfactory) 
    reactor.run() 

if __name__ == "__main__": 
    main() 

A_GREAT_TYPO_HERE(),就是要get_position()。但这是一个错字。

,并运行服务器时,终端只输出

Unhandled error in Deferred:

,别无其他。即使启用调试推迟(取消对第二和第三线),端子输出:

Unhandled error in Deferred: 
(debug: C: Deferred was created: 
C: File "nodes/test.py", line 48, in <module> 
C: main() 
C: File "nodes/test.py", line 43, in main 
C: myfactory = MyFactory() 
C: File "nodes/test.py", line 21, in __init__ 
C: self.lc.start(1) 
C: File "/home/sgsdxzy/anaconda3/lib/python3.6/site-packages/twisted/internet/task.py", line 189, in start 
C: deferred = self._deferred = defer.Deferred() 
I: First Invoker was: 
I: File "nodes/test.py", line 48, in <module> 
I: main() 
I: File "nodes/test.py", line 43, in main 
I: myfactory = MyFactory() 
I: File "nodes/test.py", line 21, in __init__ 
I: self.lc.start(1) 
I: File "/home/sgsdxzy/anaconda3/lib/python3.6/site-packages/twisted/internet/task.py", line 194, in start 
I: self() 
I: File "/home/sgsdxzy/anaconda3/lib/python3.6/site-packages/twisted/internet/task.py", line 241, in __call__ 
I: d.addErrback(eb) 
I: File "/home/sgsdxzy/anaconda3/lib/python3.6/site-packages/twisted/internet/defer.py", line 332, in addErrback 
I: errbackKeywords=kw) 
I: File "/home/sgsdxzy/anaconda3/lib/python3.6/site-packages/twisted/internet/defer.py", line 310, in addCallbacks 
I: self._runCallbacks() 
I: File "/home/sgsdxzy/anaconda3/lib/python3.6/site-packages/twisted/internet/defer.py", line 653, in _runCallbacks 
I: current.result = callback(current.result, *args, **kw) 
I: File "/home/sgsdxzy/anaconda3/lib/python3.6/site-packages/twisted/internet/task.py", line 236, in eb 
I: d.errback(failure) 
) 

它指向误差尽可能接近self.lc.start(1),但不是A_GREAT_TYPO_HERE()。我怎样才能调试我的程序,所以回溯可以指向实际的错误?

+0

你使用的是什么版本的Twisted? –

+0

@ Jean-Paul Calderone它是17.1.0,而python版本是3.6.1 – Light

回答

0

您看到的“C”和“I”行是由于您已启用延迟调试。 “C”行为您提供创建Deferred的堆栈。 “I”行为您提供延迟被“调用”的堆栈(调用其callbackerrback方法)。

这些都不是你要找的东西,看来。如果您想查看与Failure相关的堆栈,Deferred已被解雇,最直接的解决方案是确保Failure被记录(并且您有一个日志观察者,以便您可以实际看到该日志事件)。

你应该添加到您的main

from sys import stdout 
from twisted.logger import globalLogBeginner, textFileLogObserver 
globalLogBeginner.beginLoggingTo([textFileLogObserver(stdout)]) 

这指示日志流到stdout为文本。这很可能足以让你获得你想要的信息。但是,为了确保安全,您还需要显式记录失败,而不是依赖垃圾回收器为您执行此操作。所以,你也想改变:

self.lc.start(1) 

要:

# Module scope 
from twisted.logger import Logger 
logger = Logger() 

... 

# in __init__ 
d = self.lc.start(1) 
d.addErrback(lambda f: logger.failure("Loop thing problem", f)) 

(你也可能要考虑此代码出__init__并把它在startFactory代替;也可以考虑不使用一个全球性的反应器而是通过它周围作为参数)

这会给你的输出,如:。

2017-04-25T06:53:14-0400 [__main__.MyFactory#critical] Foo 
     Traceback (most recent call last): 
      File "debugging2.py", line 52, in main 
      myfactory = MyFactory() 
      File "debugging2.py", line 28, in __init__ 
      d = self.lc.start(1) 
      File "/tmp/debugging/local/lib/python2.7/site-packages/twisted/internet/task.py", line 194, in start 
      self() 
      File "/tmp/debugging/local/lib/python2.7/site-packages/twisted/internet/task.py", line 239, in __call__ 
      d = defer.maybeDeferred(self.f, *self.a, **self.kw) 
     --- <exception caught here> --- 
      File "/tmp/debugging/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 150, in maybeDeferred 
      result = f(*args, **kw) 
      File "debugging2.py", line 32, in announce 
      pos = A_GREAT_TYPO_HERE() 
     exceptions.NameError: global name 'A_GREAT_TYPO_HERE' is not defined 
+0

谢谢!记录器提供了大量有用的信息,我将阅读关于它可以提供什么的文档。 – Light