5

I'm usually fairly good at catching exceptions but this group has me perplexed. Here is the code I'm working with (it uses pywinrm):

import socket
def win_Upgrade_Check(kbByOS):
    for os in kbByOS:
        print(os)
        try:
            conn = winrm.Session(os, auth=("administrator","****"))
            for kb in kbByOS[os]:
                resp = conn.run_ps("get-hotfix -id {0}".format(kb))
                output = resp.std_out.decode('utf-8')
                error = resp.std_err
                if error:
                    print("KB{} not found on {}.".format(error,os))
                else:
                    print("{} found on {}.".format(kb,os))
        except timeout as e:
            print(e)
            pass

Here is the current word vomit of errors I'm receiving:

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/requests/packages/urllib3/connection.py", line 142, in _new_conn
(self.host, self.port), self.timeout, **extra_kw)
  File "/usr/local/lib/python3.5/dist-packages/requests/packages/urllib3/util/connection.py", line 91, in create_connection
    raise err
  File "/usr/local/lib/python3.5/dist-packages/requests/packages/urllib3/util/connection.py", line 81, in create_connection
    sock.connect(sa)
socket.timeout: timed out

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/requests/packages/urllib3/connection.py", line 142, in _new_conn
(self.host, self.port), self.timeout, **extra_kw)
  File "/usr/local/lib/python3.5/dist-packages/requests/packages/urllib3/util/connection.py", line 91, in create_connection
    raise err
  File "/usr/local/lib/python3.5/dist-packages/requests/packages/urllib3/util/connection.py", line 81, in create_connection
    sock.connect(sa)
socket.timeout: timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/requests/packages/urllib3/connectionpool.py", line 578, in urlopen
    chunked=chunked)
  File "/usr/local/lib/python3.5/dist-packages/requests/packages/urllib3/connectionpool.py", line 362, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/lib/python3.5/http/client.py", line 1106, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib/python3.5/http/client.py", line 1151, in _send_request
    self.endheaders(body)
  File "/usr/lib/python3.5/http/client.py", line 1102, in endheaders
    self._send_output(message_body)
  File "/usr/lib/python3.5/http/client.py", line 934, in _send_output
    self.send(msg)
  File "/usr/lib/python3.5/http/client.py", line 877, in send
    self.connect()
  File "/usr/local/lib/python3.5/dist-packages/requests/packages/urllib3/connection.py", line 167, in connect
    conn = self._new_conn()
  File "/usr/local/lib/python3.5/dist-packages/requests/packages/urllib3/connection.py", line 147, in _new_conn
    (self.host, self.timeout))
requests.packages.urllib3.exceptions.ConnectTimeoutError: (<requests.packages.urllib3.connection.HTTPConnection object at 0x7fc019afed30>, 'Connection to **** timed out. (connect timeout=30)')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/requests/adapters.py", line 403, in send
    timeout=timeout
  File "/usr/local/lib/python3.5/dist-packages/requests/packages/urllib3/connectionpool.py", line 623, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/usr/local/lib/python3.5/dist-packages/requests/packages/urllib3/util/retry.py", line 281, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
requests.packages.urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='****', port=5985): Max retries exceeded with url: /wsman (Caused by ConnectTimeoutError(<requests.packages.urllib3.connection.HTTPConnection object at 0x7fc019afed30>, 'Connection to **** timed out. (connect timeout=30)'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "bulletin_parse.py", line 258, in <module>
    win_Upgrade_Check(kbByOS)
  File "bulletin_parse.py", line 247, in win_Upgrade_Check
    resp = conn.run_ps("get-hotfix -id {0}".format(kb))
  File "/usr/local/lib/python3.5/dist-packages/winrm/__init__.py", line 54, in run_ps
    rs = self.run_cmd('powershell -encodedcommand {0}'.format(encoded_ps))
  File "/usr/local/lib/python3.5/dist-packages/winrm/__init__.py", line 41, in run_cmd
    shell_id = self.protocol.open_shell()
  File "/usr/local/lib/python3.5/dist-packages/winrm/protocol.py", line 132, in open_shell
    res = self.send_message(xmltodict.unparse(req))
  File "/usr/local/lib/python3.5/dist-packages/winrm/protocol.py", line 207, in send_message
    return self.transport.send_message(message)
  File "/usr/local/lib/python3.5/dist-packages/winrm/transport.py", line 173, in send_message
    response = self.session.send(prepared_request, timeout=self.read_timeout_sec)
  File "/usr/local/lib/python3.5/dist-packages/requests/sessions.py", line 585, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/requests/adapters.py", line 459, in send
    raise ConnectTimeout(e, request=request)
requests.exceptions.ConnectTimeout: HTTPConnectionPool(host='****', port=5985): Max retries exceeded with url: /wsman (Caused by ConnectTimeoutError(<requests.packages.urllib3.connection.HTTPConnection object at 0x7fc019afed30>, 'Connection to **** timed out. (connect timeout=30)'))

As you can see in my current code, I tried catching the socket.timeout first. I also tried changing it to except Exception as e, thinking a catch all would even be better than what I currently have, but that failed as well. I tried editing transport.py to add an exception for requests.exceptions.ConnectTimeout, but this isn't catching it either.

Is there something special that needs to be done since its multiple exceptions occurring?

Chad D
  • 299
  • 8
  • 21

2 Answers2

3

You can add as many different exceptions as you want:

try:
    doMyFavoriteThing()
except ValueError:
    print "Whoops!"
except timeout:
    print "Whoopsies!"
except MaxRetryError:
    print "Whoopsie daisies!"

Or if you want to catch all exceptions, since all exceptions are subclasses of the Exception class, you can do this:

try:
    doMyFavoriteThing()
except Exception as e:
    print str(e)

Of course, the first approach is generally considered to be better - you might be catching NameErrors or other silly mistakes with the other format.

Cohan
  • 4,384
  • 2
  • 22
  • 40
Athena
  • 3,200
  • 3
  • 27
  • 35
0

To answer your first question: How to catch multiple exceptions?

You can simply nest exceptions like so:

(From the python documentation. https://docs.python.org/3/tutorial/errors.html#handling-exceptions)

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise

First if there is no 'myfile.txt' The first exception will be thrown. It will look like: IOError [Errno2] No such file or directory: 'myfile.txt'

Then if there is such a file but no content then the second exception will be thrown and etc..

However to help you with your second problem of socket.timeout error not being thrown, it looks like you should change your exception to be of type socket.timeout

So changing your code to:

    except socket.timeout as e:
        print(e)

That should solve your problem.

Warosaurus
  • 520
  • 1
  • 5
  • 14