2017-04-23 11 views
0

간단한 서버 프로그램을 작성 중입니다. 그것들은 피할 수없는 오타와 새로운 코드의 다른 에러가 될 것이고 보통 파이썬 인터프리터는 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() 오류 점수 나 연기 디버깅 가능하더라도, 단말에 출력 (제 2 및 제 3 행의 주석). 추적 프로그램이 실제 오류를 가리킬 수 있도록 내 프로그램을 어떻게 디버그 할 수 있습니까?

+0

어떤 종류의 Twisted를 사용하고 있습니까? –

+0

@ Jean-Paul Calderone 17.1.0이고 파이썬 버전은 3.6.1 – Light

답변

0

보시는 "C"및 "I"라인은 지연 디버깅을 활성화했기 때문입니다. "C"라인은 Deferred가 생성 된 스택을 제공합니다. "I"줄은 Deferred가 "호출 된"스택을 제공합니다 (callback 또는 errback 메서드가 호출되었습니다).

당신이 찾고있는 것도 아닙니다. 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