Catching very specific exceptions

Roy Smith roy at
Sun Jan 22 20:30:00 CET 2006

In article <1h9k5tq.1hl7xobyyocuhN%aleax at>,
 aleax at (Alex Martelli) wrote:

> Harlin Seritt <harlinseritt at> wrote:
> > except socket.error:
> >     code goes here...
> > 
> > Of course, though, these are two separate error messages under the same
> > error handler though. I've tried:
> > 
> > except socket.error, (10061, 'Connection refused'):
> > and
> > except (socket.error, 10061, 'Connection refused'):
> > 
> > to no avail. What do I need to do to catch each one specifically?
> what I've done in such situations is
> except socket.error, e:
>   if e.errno == 10061:
>      ...
>   elif e.errno == 10060:
>      ...
>   else:
>     raise

This is not portable, however.  I'm guessing you're running on Windows, 
because the 10061 corresponds to:

                {WSAECONNREFUSED, "Connection refused"},

in Python-2.3.4/Modules/socketmodule.c:set_error().  See for more winsock error codes.

It would be nice if the socket library threw more specific exceptions, but 
given that the underlying operating systems export such a wide variety of 
system-level errors, it's not clear it's feasible, even if one wanted to 
put the effort into it.  Which brings us back to having to resort to 
unportable tricks like the above to decipher the inner meaning.

But, the real question is, WHY do you want to differentiate between these?  
The only reason to want to know which kind of connection failure you got is 
because you want to do something different on some errors.  What are you 
going to do differently when you get one of these?

socket.error: (10061, 'Connection refused')
socket.error: (10060, 'Operation timed out')

Operationally, they're pretty much the same.  One might guess that on a 
timeout, it's worth waiting a while and trying again, but it may be worth 
doing that on a refusal as well.  Perhaps you caught the remote system 
right after a reboot when the kernel network code is up, but the particular 
service you're trying to connect to hasn't started yet?  Perhaps there's 
some kind of load-limiting in use?  Perhaps the remote system is validating 
connections by reverse DNS checks, and inconsistent DNS caches are causing 
some connections to fail while others succeed?  Any of these might deserve 
a retry.

More information about the Python-list mailing list