1

The following part of my code is supposed to do exception handling during HTTP requests.

app.py

class Get:
    def __init__(self, url):
        self.url = url
    def get(self):
        waitingFactor = 1
        for i in range(0,5):   #retries if a timeout error occurs
            waitingFactor = waitingFactor*1.5
            response = requests.get(url)
            try:
                response.raise_for_status()
            except requests.exceptions.Timeout:
                #status code 408
                print("Timeout Error ocurred, program waits and retries again")
                sleep(0.5*waitingFactor)
                continue
            except requests.exceptions.TooManyRedirects:
                #status code 301
                print("Too many redirects")
                raise SystemExit()
            except requests.exceptions.HTTPError as e:
                #overally status codes 400,500, ...
                print("HTTP error, status code is "+ str(response.status_code)+
                    "\nMessage from Server: "+response.content.decode("utf-8") )
                raise SystemExit()
            except requests.exceptions.RequestException as e:
                print(e)
                raise SystemExit()
            break
        print(response)

url  =  "sample url"
getObject = Get(url)

To simulate different exceptions, I have come up with the following function, which produces fake HTTP response with a desired status code. Then, inside the class, the method request.get is replaced with the fake http response and we can test how the exception handling for different status codes work.

test.py

def getFakeHTTPResponse(statusCode, text):
    response = requests.models.Response()
    response.status_code = statusCode
    response._content = text.encode("utf-8")
    response.encoding = "utf-8"
    return response

class TestRequest(unittest.TestCase):

    @patch("app.requests.get", return_value=getFakeHTTPResponse(400,"A fake message from server"))
    def testRequest(self, mock1):
        print("hi")
        app.getObject.get()

if __name__ == '__main__':
    unittest.main()

Given the status code : 400, I get properly the following HTTP error in terminal as expected meaning my code works well:

HTTP error, status code is 400
Message from Server: Any Message

My problem is, the code does not exception handling for other cases (e.g. too many redirects, timeout, etc.). For example, If I make a fake http response with the status code: 301, I expect to get the exception handling message for too many redirects. But this does not happen at all. What is your suggestion?

Bornak
  • 65
  • 1
  • 6

1 Answers1

0

You need to try the requests.get() call in order to catch the exceptions from it

You should have ...

  ...
  waitingFactor = waitingFactor*1.5
  try:
        response = requests.get(url)
        response.raise_for_status()
  except requests.exceptions.Timeout:
  ...
Beege
  • 665
  • 4
  • 18