[Twisted-Python] How do I gracefully handle losing a connection?
fritz
twisted-python at milkpotato.org
Wed Jan 3 14:54:39 EST 2007
Hello all,
I'm building off of the ssh client example in the excellent O'Reilly
book on Twisted by Abe Fettig but I've run into some problems and I'm
not sure how I should proceed.
Basically, I've implemented additional methods in order to handle
connection issues with the client. The goal being, exiting of the
program and printing out an error message detailing why the connection
failed:
class ClientCommandFactory(protocol.ClientFactory):
...
def clientConnectionFailed(self, connector, reason):
print reason.getErrorMessage()
reactor.stop()
class CommandChannel(channel.SSHChannel):
...
def closed(self):
reactor.stop()
def openFailed(self, reason):
print reason.getErrorMessage()
reactor.stop()
class ClientCommandTransport(transport.SSHClientTransport):
...
def connectionFailed(self, reason):
print reason.getErrorMessage()
reactor.stop()
def connectionLost(self, reason):
print reason.getErrorMessage()
reactor.stop()
The problem I'm currently facing is that. The connection properly ends
and the program exits when bad data is supplied on the command line but
when the program exits cleanly CommandChannel.closed() forces a call to
ClientCommandTransport.connectionLost() and we see an exception thrown
on a connection that I thought should end cleanly:
Connection to the other side was lost in a non-clean fashion: Connection
lost.
Traceback (most recent call last):
File "/usr/lib/python2.3/site-packages/twisted/internet/posixbase.py",
line 226, in mainLoop
self.runUntilCurrent()
File "/usr/lib/python2.3/site-packages/twisted/internet/base.py", line
555, in runUntilCurrent
call.func(*call.args, **call.kw)
File "/usr/lib/python2.3/site-packages/twisted/internet/base.py", line
414, in _continueSystemEvent
callable(*args, **kw)
File "/usr/lib/python2.3/site-packages/twisted/internet/base.py", line
375, in disconnectAll
failure.Failure(main.CONNECTION_LOST))
--- <exception caught here> ---
File "/usr/lib/python2.3/site-packages/twisted/python/log.py", line
53, in callWithLogger
return callWithContext({"system": lp}, func, *args, **kw)
File "/usr/lib/python2.3/site-packages/twisted/python/log.py", line
38, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "/usr/lib/python2.3/site-packages/twisted/python/context.py",
line 59, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/usr/lib/python2.3/site-packages/twisted/python/context.py",
line 37, in callWithContext
return func(*args,**kw)
File "/usr/lib/python2.3/site-packages/twisted/internet/tcp.py", line
554, in connectionLost
Connection.connectionLost(self, reason)
File "/usr/lib/python2.3/site-packages/twisted/internet/tcp.py", line
402, in connectionLost
protocol.connectionLost(reason)
File "code/python/sshclient/sshclient.py", line 33, in connectionLost
reactor.stop()
File "/usr/lib/python2.3/site-packages/twisted/internet/base.py", line
342, in stop
raise RuntimeError, "can't stop reactor that isn't running"
exceptions.RuntimeError: can't stop reactor that isn't running
If I remove reactor.stop() from ClientCommandTransport.connectionLost()
I then face the issue of some connection problems not being handled
correctly and the program will go idle on some bad connections.
So my question is, how can I fix my code to handle these exceptions and
all cases of bad connections and connections terminating abnormally?
Where should I implement connectionLost() and connectionFailed() and
how can I cleanly disconnect from the SSH server without seeing ugly
errors like the one above?
Thanks in advance,
Fritz
More information about the Twisted-Python
mailing list