[Twisted-Python] newbie question: error handling
![](https://secure.gravatar.com/avatar/9bd49d5d6e7a2e7c0eb54474dd288526.jpg?s=120&d=mm&r=g)
Hi All, I'm currently migrating my irc client to twisted, and things look promising. However, I can't figure out the following things: My protocol is derived from protocols.basic.LineReceiver (which in turn derives from protocol.Protocol.protocol). How can I determine what specific error condition caused connectionLost() or connectionFailed()? I.e. connection refused, unknown hostname, no route to host, etc (the standard errno stuff). Also, how can I determine if Linereceived.sendLine() (or Protocol.Transport.write()) failed? It doesn't seem to return an error value or raise Exceptions, and depending on the invocation of connectionLost makes things perhaps too asynchronous.. Cheers, Ivo -- Drs. I.R. van der Wijk -=- Brouwersgracht 132 Amaze Internet Services V.O.F. 1013 HA Amsterdam, NL -=- Tel: +31-20-4688336 Linux/Web/Zope/SQL/MMBase Fax: +31-20-4688337 Network Solutions Web: http://www.amaze.nl/ Consultancy Email: ivo@amaze.nl -=-
![](https://secure.gravatar.com/avatar/e1554622707bedd9202884900430b838.jpg?s=120&d=mm&r=g)
On Sun, 2001-12-30 at 17:44, Ivo van der Wijk wrote:
Currently you can't. This is the first request I'm aware of to be made aware of the actual errno that caused the connection to fail; the distinction between connectionFailed and connectionLost seemed to be the big one. The place you'd have to fix would be twisted.internet.tcp.Connection.(doRead|writeSomeData). Similarly in twisted.internet.udp. Patches accepted :-).
If you need this level of guarantee, you need a protocol which will send acks for messages as they've been received. There is no such thing as "too asynchronous" -- there is "synchronous", "asynchronous", and "sometimes stuck doing something with one client while the rest of the server hangs..." :-). This is the same question as previously, really; if a write "fails", then the connection has been lost. Knowing that a connection failed during a write and getting an errno would give you all the same information. Keep in mind that a write "succeeding" might just mean that the memory was succesfully copied into a buffer for your OS kernel to send; the other side of the connection may never have received it. -- ______ you are in a maze of twisted little applications, all | |_\ remarkably consistent. | | -- glyph lefkowitz, glyph @ twisted matrix . com |_____| http://www.twistedmatrix.com/
![](https://secure.gravatar.com/avatar/9bd49d5d6e7a2e7c0eb54474dd288526.jpg?s=120&d=mm&r=g)
On Mon, Dec 31, 2001 at 09:08:52AM -0600, Glyph Lefkowitz wrote:
Okay. How about an error parameter to connectionLost|Failed that would contain the actual error? Unfortunately, this would break existing code, so you would end up with names like connectionFailedWithError. Alternatively, the protocol can query the transport for the (last) error code. Is the python error mechanism platform independent enough, or should there be an abstraction of the errno/errstr mechanism?
Well, you could return an error if the connection is obviously closed already (and perhaps return the error received when the connection was close asynchronously) - i.e. when it's clear that the async. write will fail. The rest can be handled right away. Also, I don't know if twisted will always attempt to send/flush data right away and catch EWOULDBLOCK, or if flushing will only be triggered by select() on write fd's. In the former case, if writing won't block (which may be quite often the case?), you catch errors immediately as well..
I basically meant succeeding as with socket.recv/send(). Cheers, Ivo -- Drs. I.R. van der Wijk -=- Brouwersgracht 132 Amaze Internet Services V.O.F. 1013 HA Amsterdam, NL -=- Tel: +31-20-4688336 Linux/Web/Zope/SQL/MMBase Fax: +31-20-4688337 Network Solutions Web: http://www.amaze.nl/ Consultancy Email: ivo@amaze.nl -=-
![](https://secure.gravatar.com/avatar/e1554622707bedd9202884900430b838.jpg?s=120&d=mm&r=g)
On Mon, 2001-12-31 at 12:27, Ivo van der Wijk wrote:
This was the way Twisted originally worked; we wrote a TON of code and this parameter was never used :-). Feel free to add it, though; your connectionFailedWithError approach sounded like a good one.
I *could*, but why would I? This means that your errors have to be handled in two places instead of one, and it will only *sometimes* actually be handled by one of those two places, depending on the OS buffer sizes and the direction of prevailing winds. There are lots of places where a connection can be dropped, and there are lots of reasons for it. Unifying them into a single "connection has been lost" failure path is in general a good thing; I could understand wanting more information about that failure (your previous request) but wanting the failure case to be exposed to your code through numerous paths -- all of which must be handled and the distinction between which is VERY difficult to test -- seems like a naive regression to a lower-level API.
Why is this useful information to have at the application layer? -- ______ you are in a maze of twisted little applications, all | |_\ remarkably consistent. | | -- glyph lefkowitz, glyph @ twisted matrix . com |_____| http://www.twistedmatrix.com/
![](https://secure.gravatar.com/avatar/e1554622707bedd9202884900430b838.jpg?s=120&d=mm&r=g)
On Sun, 2001-12-30 at 17:44, Ivo van der Wijk wrote:
Currently you can't. This is the first request I'm aware of to be made aware of the actual errno that caused the connection to fail; the distinction between connectionFailed and connectionLost seemed to be the big one. The place you'd have to fix would be twisted.internet.tcp.Connection.(doRead|writeSomeData). Similarly in twisted.internet.udp. Patches accepted :-).
If you need this level of guarantee, you need a protocol which will send acks for messages as they've been received. There is no such thing as "too asynchronous" -- there is "synchronous", "asynchronous", and "sometimes stuck doing something with one client while the rest of the server hangs..." :-). This is the same question as previously, really; if a write "fails", then the connection has been lost. Knowing that a connection failed during a write and getting an errno would give you all the same information. Keep in mind that a write "succeeding" might just mean that the memory was succesfully copied into a buffer for your OS kernel to send; the other side of the connection may never have received it. -- ______ you are in a maze of twisted little applications, all | |_\ remarkably consistent. | | -- glyph lefkowitz, glyph @ twisted matrix . com |_____| http://www.twistedmatrix.com/
![](https://secure.gravatar.com/avatar/9bd49d5d6e7a2e7c0eb54474dd288526.jpg?s=120&d=mm&r=g)
On Mon, Dec 31, 2001 at 09:08:52AM -0600, Glyph Lefkowitz wrote:
Okay. How about an error parameter to connectionLost|Failed that would contain the actual error? Unfortunately, this would break existing code, so you would end up with names like connectionFailedWithError. Alternatively, the protocol can query the transport for the (last) error code. Is the python error mechanism platform independent enough, or should there be an abstraction of the errno/errstr mechanism?
Well, you could return an error if the connection is obviously closed already (and perhaps return the error received when the connection was close asynchronously) - i.e. when it's clear that the async. write will fail. The rest can be handled right away. Also, I don't know if twisted will always attempt to send/flush data right away and catch EWOULDBLOCK, or if flushing will only be triggered by select() on write fd's. In the former case, if writing won't block (which may be quite often the case?), you catch errors immediately as well..
I basically meant succeeding as with socket.recv/send(). Cheers, Ivo -- Drs. I.R. van der Wijk -=- Brouwersgracht 132 Amaze Internet Services V.O.F. 1013 HA Amsterdam, NL -=- Tel: +31-20-4688336 Linux/Web/Zope/SQL/MMBase Fax: +31-20-4688337 Network Solutions Web: http://www.amaze.nl/ Consultancy Email: ivo@amaze.nl -=-
![](https://secure.gravatar.com/avatar/e1554622707bedd9202884900430b838.jpg?s=120&d=mm&r=g)
On Mon, 2001-12-31 at 12:27, Ivo van der Wijk wrote:
This was the way Twisted originally worked; we wrote a TON of code and this parameter was never used :-). Feel free to add it, though; your connectionFailedWithError approach sounded like a good one.
I *could*, but why would I? This means that your errors have to be handled in two places instead of one, and it will only *sometimes* actually be handled by one of those two places, depending on the OS buffer sizes and the direction of prevailing winds. There are lots of places where a connection can be dropped, and there are lots of reasons for it. Unifying them into a single "connection has been lost" failure path is in general a good thing; I could understand wanting more information about that failure (your previous request) but wanting the failure case to be exposed to your code through numerous paths -- all of which must be handled and the distinction between which is VERY difficult to test -- seems like a naive regression to a lower-level API.
Why is this useful information to have at the application layer? -- ______ you are in a maze of twisted little applications, all | |_\ remarkably consistent. | | -- glyph lefkowitz, glyph @ twisted matrix . com |_____| http://www.twistedmatrix.com/
participants (2)
-
Glyph Lefkowitz
-
Ivo van der Wijk