我的问题是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.
所以我打算如何使用它,但是当Exception冒泡时,.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
答案 0 :(得分:1)
这就是我所做的。为我工作。
首次阅读错误时,请将其保存为如下变量: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')))
答案 1 :(得分:0)
错误对象可能从网络中读取。网络是不可寻找的 - 你不能回到一般情况。
您可以将err
替换为从缓冲区(如io.BytesIO()
)而非网络读取的新HTTPError实例,例如(未经测试):
content = err.read()
self.log.exception(content)
raise HTTPError(err.url, err.code, err.reason, err.headers, io.BytesIO(content))
虽然我不确定你应该 - 在一个地方处理错误,例如,重新引用更多特定于应用程序的异常,或者将日志记录留给上游处理程序。