Catching very specific exceptions

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Harlin Seritt

    Catching very specific exceptions

    I am running the following code:

    import socket

    host = '9.9.45.103'
    port = 10001

    conn = socket.socket(s ocket.AF_INET, socket.SOCK_STR EAM)
    conn.connect((h ost, port))

    When conn.connect() is run, there can be two different exceptions:

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

    How can I set up exceptions for each of these differently? Normally I
    would use:

    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?

    Thanks,

    Harlin Seritt

  • Alex Martelli

    #2
    Re: Catching very specific exceptions

    Harlin Seritt <harlinseritt@y ahoo.com> wrote:
    [color=blue]
    > 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?[/color]

    what I've done in such situations is

    except socket.error, e:
    if e.errno == 10061:
    ...
    elif e.errno == 10060:
    ...
    else:
    raise

    Not sure the code in a socket.error has attributename 'errno', but I
    hope you get the general idea.


    Alex

    Comment

    • Peter Hansen

      #3
      Re: Catching very specific exceptions

      Alex Martelli wrote:[color=blue]
      > what I've done in such situations is
      >
      > except socket.error, e:
      > if e.errno == 10061:
      > ...
      > elif e.errno == 10060:
      > ...
      > else:
      > raise
      >
      > Not sure the code in a socket.error has attributename 'errno', but I
      > hope you get the general idea.[/color]

      If it does not, or as a more generally applicable solution (though less
      readable), one can use the args attribute:

      except socket.error, e:
      if e.args[0] == 10061:
      ...
      elif e.args[0] == 10060:
      ...

      args is just the tuple formed from the positional arguments passed to
      the __init__() of the exception object when it is created, as if you did:

      class Exception:
      def __init__(self, *args):
      self.args = args


      -Peter

      Comment

      • Roy Smith

        #4
        Re: Catching very specific exceptions

        In article <1h9k5tq.1hl7xo byyocuhN%aleax@ mail.comcast.ne t>,
        aleax@mail.comc ast.net (Alex Martelli) wrote:
        [color=blue]
        > Harlin Seritt <harlinseritt@y ahoo.com> wrote:
        >[color=green]
        > > 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?[/color]
        >
        > what I've done in such situations is
        >
        > except socket.error, e:
        > if e.errno == 10061:
        > ...
        > elif e.errno == 10060:
        > ...
        > else:
        > raise[/color]

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

        {WSAECONNREFUSE D, "Connection refused"},

        in Python-2.3.4/Modules/socketmodule.c: set_error(). See
        http://tinyurl.com/gth2 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.

        Comment

        • Harlin Seritt

          #5
          Re: Catching very specific exceptions

          Thanks for the effort on this last post, Roy. You asked what I was
          hoping to do differently on these two very minutely different error
          messages. What I have been trying to do for some time is to write a
          ping client (for Win32 platform -- Yes, I develop almost exclusively
          for Win32 environment, unfortunately) that would be a bit less buggy
          than ones already written, avoid Twisted, and not even involve myself
          in pynms (way overkill for what I want and need).

          I am finding that with the many quirks (and really bad foundation for
          Win32 APIs) that I am having to write a lot of voodoo code so to speak.
          If I use a dummy port... let's say port 10001 for example... I can
          attempt to connect to a machine at this port. If I get an error that
          says "Connection refused", I know that the node is up but is just not
          going to allow a connection. On the other hand, if I try to connect to
          a node and it's really not up, I'll get a "Connection timed out" error.
          In this manner I can really tell if a node is up or not (providing a
          TCP/IP stack is installed there). This really what I've wanted. I am
          not so concerned whether or not the node pongs back in a certain amount
          of time.

          Yeah normally it's annoying when people ask what you're trying to do
          when you ask a specific question, but in this case it's probably
          necessary to explain myself before some are willing to help out. I'm
          really not interested in even negotiating a successful connection on a
          specific port, but this is just a way to tell if something is up or
          down (and perhaps the only real way to do it running from a Win32
          platform). Thanks for the help. However, if you do have suggestions on
          how to get this done better, I am more than glad to hear it!

          Thanks,

          Harlin Seritt

          Comment

          • Roy Smith

            #6
            Re: Catching very specific exceptions

            "Harlin Seritt" <harlinseritt@y ahoo.com> wrote:[color=blue]
            > I am finding that with the many quirks (and really bad foundation for
            > Win32 APIs) that I am having to write a lot of voodoo code so to speak.[/color]

            Yeah, tell me about it. My current project at work is porting our IPv6
            management package (including ICMP ping) to windows; "many quirks" would be
            a good way to describe it!
            [color=blue]
            > If I use a dummy port... let's say port 10001 for example... I can
            > attempt to connect to a machine at this port. If I get an error that
            > says "Connection refused", I know that the node is up but is just not
            > going to allow a connection.[/color]

            Maybe. It could be that some firewall between you and the target is
            blocking things. Depending on how the firewall is programmed, this may
            show up as a timeout or as a connection refused (although the former would
            be more common).

            It's also not always a clear-cut question what "up" means. Some operating
            systems can get into modes where for all intents and purposes they've
            crashed, but they're still answering pings and/or actively refusing
            connections.

            The traditional way to tell if a node is up is to send it an ICMP echo
            request, rather than trying to connect to a TCP port. You might want to
            look into using that instead of trying to connect to random ports. Not
            that that ICMP doesn't have its own problems :-)

            Comment

            • Harlin Seritt

              #7
              Re: Catching very specific exceptions

              Reasons why it still won't work:

              * Firewall
              * Unknown-modes-operating-systems-get-into

              Yeah, I dont think these things can be avoided. Nonetheless, if I can
              come up with some way (via help from this group--thank God!) to find if
              the node is up (barring the two aforementioned reasons), I am doing
              well. Maybe my standards are not so high. :-|

              Nonetheless, thanks for the help and the commentary. I was beginning to
              think I was losing my mind.

              Harlin

              Comment

              Working...