My problem is with error handling of the python urllib error object. I am unable to read the error message while still keeping it intact in the error object, for it to be consumed later.
response = urllib.request.urlopen(request) # request that will raise an error
response.read()
response.read() # is empty now
# Also tried seek(0), that does not work either.
So this how I intend to use it, but when the Exception bubbles up, the.read()
second time is empty.
try:
response = urllib.request.urlopen(request)
except urllib.error.HTTPError as err:
self.log.exception(err.read())
raise err
I tried making a deepcopy of the err object,
import copy
try:
response = urllib.request.urlopen(request)
except urllib.error.HTTPError as err:
err_obj_copy = copy.deepcopy(err)
self.log.exception(
"Method:{}\n"
"URL:{}\n"
"Data:{}\n"
"Details:{}\n"
"Headers:{}".format(method, url, data, err_obj_copy.read(), headers))
raise err
but copy is unable to make a deepcopy and throws an error -
TypeError: __init__() missing 5 required positional arguments: 'url', 'code', 'msg', 'hdrs', and 'fp'
.
How do I read the error message, while still keeping it intact in the object?
I do know how to do it using requests
, but I am stuck with legacy code and need to make it work with urllib
resp.read()
so that you pass in the raw bytes back toHTTPError
instead of re-encoding the text. See @jf's answer above. – Neace