Не удается прочитать сообщение об ошибке urllib, как только оно прочитано ()
Моя проблема с обработкой ошибок объекта ошибки python urllib. Я не могу прочитать сообщение об ошибке, сохраняя его нетронутым в объекте ошибки, чтобы его можно было использовать позже.
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.
Так вот, как я собираюсь использовать это, но когда всплывает Исключение,.read()
второй раз пуст.
try:
response = urllib.request.urlopen(request)
except urllib.error.HTTPError as err:
self.log.exception(err.read())
raise err
Я попытался сделать глубокую копию ошибочного объекта,
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
но копия не может сделать глубокую копию и выдает ошибку -TypeError: __init__() missing 5 required positional arguments: 'url', 'code', 'msg', 'hdrs', and 'fp'
,
Как мне прочитать сообщение об ошибке, сохранив его в целости и сохранности в объекте?
Я знаю, как это сделать, используя requests
, но я застрял с устаревшим кодом и нужно, чтобы он работал с urllib
2 ответа
Это то, что я сделал. Работал на меня.
При первом чтении ошибки сохраните ее в переменную, например: msg = response.read().decode('utf8')
, Затем вы можете создать новый HTTPError
экземпляр, с сообщением, и распространять его.
resp = urllib.request.urlopen(request)
msg = resp.read().decode('utf8')
self.log.exception(msg)
raise HTTPError(resp.url, resp.code, resp.reason, resp.headers, io.BytesIO(bytes(msg, 'utf8')))
Объект ошибки может считываться из сети. Сеть недоступна для поиска - вы не можете вернуться назад в общем случае.
Вы могли бы заменить err
с новым экземпляром HTTPError, который читает из буфера (например, io.BytesIO()
) вместо сети, например (не проверено):
content = err.read()
self.log.exception(content)
raise HTTPError(err.url, err.code, err.reason, err.headers, io.BytesIO(content))
Хотя я не уверен, что вам следует - вместо этого обработать ошибку в одном месте, например, повторно вызвать более специфичное для приложения исключение или оставить ведение журнала для вышестоящего обработчика.