2

I am trying to read a status from four web servers that monitor fluid tanks with an HTTP connection. It is not unusual for one or more of these servers to not be present, but that's okay, I just want to record a timeout error and continue to the other servers and get their status. I cannot figure out how to handle the timeout when it occurs? And always open to any other critique on this code... I'm brand new to Python.

# Fluid tank Reader
import http.client

activeTanks = 4;
myTanks=[100,100,100,100]

for tank in range(0,activeTanks):
    tankAddress = ("192.168.1.4"+str(tank))
    conn = http.client.HTTPConnection(tankAddress, timeout=1)
    ##  How do I handle the exception and finish the For Loop?
    conn.request("GET", "/Switch=Read")
    r1 = conn.getresponse()
    conn.close()
    myTanks[tank] = int(r1.read().decode('ASCII').split("...")[1])

print(myTanks)  # this will pass data back to a main loop later
1
  • Could you please add the complete stacktrace of such an error? Commented Apr 13, 2018 at 15:25

2 Answers 2

4

You should add handler for socket.timeout exception:

import http.client
import socket


activeTanks = 4  # no semicolon here
myTanks = [100, 100, 100, 100]

for tank in range(0, activeTanks):
    tankAddress = ("192.168.1.4" + str(tank))
    conn = http.client.HTTPConnection(tankAddress, timeout=1)

    try:
        conn.request("GET", "/Switch=Read")
    except socket.timeout as st:
        # do some stuff, log error, etc.
        print('timeout received')
    except http.client.HTTPException as e:
        # other kind of error occured during request
        print('request error')
    else:  # no error occurred
        r1 = conn.getresponse()
        # do some stuff with response
        myTanks[tank] = int(r1.read().decode('ASCII').split("...")[1])
    finally:  # always close the connection
        conn.close()

print(myTanks)
Sign up to request clarification or add additional context in comments.

3 Comments

The break in the except block is wrong. The OP clearly wanted to continue the loop and just log an error. But thinking about it, wouldn't it actually be the HTTPConnection instantiation that would throw the exception if the server was unavailable?
Instantiation will throw an error only if the port is specified and invalid. In the example code above there is no port mentioned.
Ivan and shmee... You guys are awesome! I googled a lot trying to find an answer but only got more confused. Your help was perfect and really quick! I'll post my final code in case it helps someone else in the future.
0

As in other languages, you catch the exception and treat it: (N.B.: I placed it there, but it's up to you)

** Fluid tank Reader
import http.client

activeTanks = 4;
myTanks=[100,100,100,100]

for tank in range(0,activeTanks):
    tankAddress = ("192.168.1.4"+str(tank))
    conn = http.client.HTTPConnection(tankAddress, timeout=1)
    ##  How do I handle the exception and finish the For Loop?
    try:
        conn.request("GET", "/Switch=Read")
        r1 = conn.getresponse()
        myTanks[tank] = int(r1.read().decode('ASCII').split("...")[1])
    except http.client.HTTPException:
        do something
    finally:
        conn.close() #ensures you cleanly close your connection each time, thanks @schmee


print(myTanks)  **  this will pass data back to a main loop later

1 Comment

I would recommend to put the conn.request and conn.getresponse alone into the try block. Then you can have the conn.close() in a finally block and don't need to worry to have your connection properly closed, no matter what logical path you'll end up with eventually.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.