Reputation: 1006
I'm working on a basic socket client program in python and I'm not totally sure how to handle exceptions. This is what I did up to now:
TCP_IP = '..............'
TCP_PORT = 4950
MESSAGE = "o3"
BUFFER_SIZE = 2048
data = ""
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5.0)
try:
s.connect((TCP_IP, TCP_PORT))
except socket.error:
#write error code to file
s.close()
try:
s.sendall(MESSAGE)
except socket.error:
#write to file or whatever
s.close()
try:
data = s.recv(BUFFER_SIZE)
except socket.error:
#write to file or whatever
s.close()
finally:
s.close()
The code is working as I want, but I'm not sure if I should nest try/catch blocks or not? Should I put socket.socket
into try/catch block too?
Second question, what will s.settimeout()
do in my case? As far as I understood the documentation, it will throw an exception after 5 seconds, but for what? Just connect
or will it do the same for sendall
and recv
?
Upvotes: 2
Views: 34719
Reputation: 16137
Since you're doing exactly the same actions in all the exception blocks and catching the same socket.error
exception, you could put s.connect
, s.sendall
and s.recv
in the same try:
block. Like so:
try:
s.connect((TCP_IP, TCP_PORT))
s.sendall(MESSAGE)
data = s.recv(BUFFER_SIZE)
except socket.error:
#write error code to file
finally:
s.close()
Note that since s.close
is also in the finally
section in your example, it will always get called, even after an exception has occurred. So you'd end up with another exception occurring when you try to close an already closed socket. By not putting it in the except
block and only in finally
, you can avoid that situation.
If you do intend to handle each error in a different way, then you can leave them separate as you already have. But make sure to break
/return
at the end of the exception block so that you don't try the next. It's done that way in the socket examples, by using a continue
in the loop.
Nesting them would help if you wanted to do something different in the exception block. But if not you'd be repeating the except
block every time. And if you wanted to do something different, when you exit the nested-try
s, you wouldn't be certain of which level it has completed or raised an exception - would need to use flag values etc. to merely track that. So for your example of the same error handling code, at the very least, do something like this in your except
block:
except socket.error as e:
socket_error_handler(e, s)
def socket_error_handler(exception, socket):
#write error code to file
etc.
Should I put
socket.socket
into try/catch block too?
They do that in the examples, linked above.
Apart from logging, you shouldn't really be doing the same exception handling at each stage. Probably need to handle those separately.
Part 2:
s.settimeout(5.0)
sets the timeout for each socket operation, not just the first connect. Also implies that it's in blocking mode.
Upvotes: 5