dmwm / DBSClient

Apache License 2.0
3 stars 8 forks source link

WIP: Add proper printout of HTTP error and decode JSON only if HTTP code is 200 #45

Closed vkuznet closed 2 years ago

vkuznet commented 2 years ago

@yuyiguo , @amaltaro here I suggest proper fix to handle FE errors. WIth this PR if I do incorrect call to DBS, e.g.

from dbs.apis.dbsClient import *

url="https://cmsweb-testbed.cern.ch/dbs/bla/DBSReader"
api = DbsApi(url=url, debug=1)
res = api.help()

then, I can much better error like this:

TTP=GET URL=https://cmsweb-testbed.cern.ch:8443/dbs/bla/DBSReader method=help params={} data={} headers={'Content-Type': 'application/json', 'Accept': 'application/json', 'UserID': 'valya@vocms0182.cern.ch', 'User-Agent': 'DBSClient/Unknown/'}
### HTTPError ###
URL: https://cmsweb-testbed.cern.ch:8443/dbs/bla/DBSReader/help
HTTP code: 400
HTTP Message: Bad Request
HTTP Header: HTTP/1.1 400 Bad Request
Date: Fri, 05 Nov 2021 14:35:22 GMT
Server: Apache
Content-Length: 226
Connection: close
Content-Type: text/html; charset=iso-8859-1

HTTP Body
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>

Traceback (most recent call last):
  File "/data/users/vk/dbs/DBS/DBSClient/src/python/dbs/apis/dbsClient.py", line 440, in __parseForException
    data = json.loads(data)
  File "/data/users/vk/anaconda3/lib/python3.8/json/__init__.py", line 357, in loads
    return _default_decoder.decode(s)
  File "/data/users/vk/anaconda3/lib/python3.8/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/data/users/vk/anaconda3/lib/python3.8/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./t.py", line 5, in <module>
    res = api.help()
  File "/data/users/vk/dbs/DBS/DBSClient/src/python/dbs/apis/dbsClient.py", line 506, in help
    return self.__callServer("help", params=kwargs)
  File "/data/users/vk/dbs/DBS/DBSClient/src/python/dbs/apis/dbsClient.py", line 404, in __callServer
    self.__parseForException(http_error)
  File "/data/users/vk/dbs/DBS/DBSClient/src/python/dbs/apis/dbsClient.py", line 442, in __parseForException
    raise http_error
  File "/data/users/vk/dbs/DBS/DBSClient/src/python/dbs/apis/dbsClient.py", line 402, in __callServer
    self.http_response = method_func(self.url, method, params, data, request_headers)
  File "/data/users/vk/dbs/DBS/DBSClient/dbs3-pycurl-3.17.4/src/python/RestClient/RestApi.py", line 34, in get
    return http_request(self._curl)
  File "/data/users/vk/dbs/DBS/DBSClient/dbs3-pycurl-3.17.4/src/python/RestClient/RequestHandling/HTTPRequest.py", line 62, in __call__
    raise HTTPError(effective_url, http_code, http_response.msg, http_response.raw_header, http_response.body)
RestClient.ErrorHandling.RestClientExceptions.HTTPError: HTTP Error 400: Bad Request

As you can see now it properly shows the response from FE which will allow easily identify what's wrong.

I also provide a check for HTTP code and return proper JSON if the code is not 200. The JSON decoding (in my opinion) should only happen when response is OK.

I'm not suggesting to merge it but give you an example how to better handle the errors.

yuyiguo commented 2 years ago

not necessary.