I understand the basic try: except: finally: syntax for pythons error handling. What I don't understand is how to find the proper error names to make readable code.
For example:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.settimeout(60)
char = s.recv(1)
except socket.timeout:
pass
so if socket raises a timeout, the error is caught. How about if I am looking for a connection refused. I know the error number is 10061. Where in the documentation do I look to find a meaning full name such as timeout. Would there be a similar place to look for other python modules? I know this is a newbie question but I have been putting in error handling my my code for some time now, without actually knowing where to look for error descriptions and names.
EDIT:
Thanks for all your responses.
would
except socket.error, exception:
if exception.errno == ETIMEDOUT:
pass
achieve the same result as
except socket.timeout:
pass
To achieve what you want, you'll have to grab the raised exception, extract the error code stored into, and make some if comparisons against errno codes:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.settimeout(60)
char = s.recv(1)
except socket.error, exception:
if exception.errno == errno.ECONNREFUSED:
# this is a connection refused
# or in a more pythonic way to handle many errors:
{
errno.ECONNREFUSED : manage_connection_refused,
errno.EHOSTDOWN : manage_host_down,
#all the errors you want to catch
}.get(exception.errno, default_behaviour)()
except socket.timeout:
pass
with :
def manage_connection_refused():
print "Connection refused"
def manage_host_down():
print "Host down"
def default_behaviour():
print "error"
You will get an error with an errno, which is described in the errno documentation. 10061 is only valid for WinSock.
According to socket, socket.error values are defined in the errno module.
Related
sock1.settimeout(2)
conn.settimeout(1) #conn comes from sock1
except socket.timeout, e:
print <responsible socket>
Is there a way to distinguish the socket responsible for the timeout?
Perhaps I'm doing something wrong if I have two sockets that are timing out.
As far as I can tell, there's nothing in the socket.timeout exception object that identifies the socket. So you need to keep track of which socket you're reading from, that will be the one that timed out:
try:
cursock = sock1
data = sock1.recv(bufsize)
cursock = conn
data1 = conn.recv(bufsize)
except socket.timeout, e:
print cursock
Or you could wrap try/except around each recv call. You could put this into a helper function:
def try_recv(sock, bufsize, flags=0):
try:
return sock.recv(bufsize, flag)
except socket.timeout, e:
print sock
I am trying to create a script that will, on error, attempt to reconnect again. But even after the receiving server has been started it still will not connect
send_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while True:
try: #Cant get it to make connection after retrying
send_sock.connect((ip, port)) #always throws Con Refused when tryed
break
except socket.error:
print "Connection Failed, Retrying.."
time.sleep(1)
send_sock.send("hi")
edit: Corrected "try:" typo
Had this same issue myself, once I had worked it out it was actually quite a simple solution, all you need to do is create the send_sock before every connection attempt. Not sure why this fixes it but it does for me. Hope it does for you too.
while True:
try:#moved this line here
send_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
send_sock.connect((ip, port)) #no longer throws error
break
except socket.error:
print "Connection Failed, Retrying.."
time.sleep(1)
send_sock.send("hi")
Python socket will give you a error that should help with debugging your problem. For your example.
try:
send_sock.connect((ip, port))
except socket.error as error:
print("Connection Failed **BECAUSE:** {}").format(error)
Second of all you should almost never use while true: [...] as its just going to cause all sorts of problems. In this case you could put in a counter and loop on that break after X attempts.
While counter < 100:
try:
send_sock.connect((ip, port))
except socket.error as error:
print("Connection Failed **BECAUSE:** {}").format(error)
print("Attempt {} of 100").format(counter)
counter += 1
Check out the Python Docs on socket exceptions for more info.
I have a socket-connection going on and I wanna improve the exception handling and I'm stuck. Whenever I call socket.connect(server_address) with an invalid argument the program stops, but doesn't seem to raise an exception. Here is my code:
import socket
import sys
import struct
class ARToolkit():
def __init__(self):
self.x = 0
self.y = 0
self.z = 0
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.logging = False
def connect(self,server_address):
try:
self.sock.connect(server_address)
except socket.error, msg:
print "Couldnt connect with the socket-server: %s\n terminating program" % msg
sys.exit(1)
def initiate(self):
self.sock.send("start_logging")
def log(self):
self.logging = True
buf = self.sock.recv(6000)
if len(buf)>0:
nbuf = buf[len(buf)-12:len(buf)]
self.x, self.y, self.z = struct.unpack("<iii", nbuf)
def stop_logging(self):
print "Stopping logging"
self.logging = False
self.sock.close()
The class maybe looks a bit wierd but its used for receiving coordinates from another computer running ARToolKit. Anyway, the issue is at the function connect():
def connect(self,server_address):
try:
self.sock.connect(server_address)
except socket.error, msg:
print "Couldnt connect with the socket-server: %s\n terminating program" % msg
sys.exit(1)
If I call that function with a random IP-address and portnumber the whole program just stops up at the line:
self.sock.connect(server_address)
The documentation I've read states that in case of an error it will throw a socket.error-exception. I've also tried with just:
except Exception, msg:
This, if I'm not mistaken, will catch any exceptions, and still it yields no result. I would be very grateful for a helping hand. Also, is it okay to exit programs using sys.exit when an unwanted exception occurs?
Thank you
If you have chosen a random, but valid, IP address and port, socket.connect() will attempt to make a connection to that endpoint. By default, if no explicit timeout is set for the socket, it will block while doing so and eventually timeout, raising exception socket.error: [Errno 110] Connection timed out.
The default timeout on my machine is 120 seconds. Perhaps you are not waiting long enough for socket.connect() to return (or timeout)?
You can try reducing the timeout like this:
import socket
s = socket.socket()
s.settimeout(5) # 5 seconds
try:
s.connect(('123.123.123.123', 12345)) # "random" IP address and port
except socket.error, exc:
print "Caught exception socket.error : %s" % exc
Note that if a timeout is explicitly set for the socket, the exception will be socket.timeout which is derived from socket.error and will therefore be caught by the above except clause.
The problem with your last general exception is the colon placement. It needs to be after the entire exception, not after the except statement. Thus to capture all exceptions you would need to do:
except Exception,msg:
However from Python 2.6+ you should use the as statement instead of a comma like so:
except Exception as msg:
I was able to run the code fine (note you need to throw in a tuple to the connect method). If you want to specifically catch only socket errors then you would need to except the socket.error class. Like you have:
except socket.error as msg:
If you want to make sure that a tuple is entered simply add another exception loop:
except socket.error as msg:
print "Socket Error: %s" % msg
except TypeError as msg:
print "Type Error: %s" % msg
Codes like this:
import socket, sys
try:
address = ('127.0.0.1', 31500)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(address)
except Exception:
errType, errValue, errTraceback = sys.exc_info()
# or
# handle the Exception it throw out ?
What I want to get is the errcode like 10060 which means connection time out, thanks for any help :)
Use
except EnvironmentError as e:
print e.errno
Hey I'm wondering how to handle specific error codes. For example, [Errno 111] Connection refused
I want to catch this specific error in the socket module and print something.
If you want to get the error code, this seems to do the trick;
import errno
try:
socket_connection()
except socket.error as error:
if error.errno == errno.ECONNREFUSED:
print(os.strerror(error.errno))
else:
raise
You can look up errno error codes.
On Unix platforms, at least, you can do the following.
import socket, errno
try:
# Do something...
except socket.error as e:
if e.errno == errno.ECONNREFUSED:
# Handle the exception...
else:
raise
Before Python 2.6, use e.args[ 0 ] instead of e.errno.
This seems hard to do reliably/portably but perhaps something like:
import socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 4167))
except socket.error, e:
if 'Connection refused' in e:
print '*** Connection refused ***'
which yields:
$ python socketexception.py
*** Connection refused ***
Pretty yucky though.
I'm developing on Windows and found myself in the same predicament. But the error message always contains the error number. Using that information I just convert the exception to a string str(Exception), convert the error code I wanna check for to a string str(socket.errno.ERRORX) and check if the error code is in the exception.
Example for a connection reset exception:
except Exception as errorMessage:
if str(socket.errno.ECONNRESET) in str(errorMessage):
print("Connection reset")
#etc...
This avoids locale specific solutions but is still not platform independent unfortunately.