读取后无法读取urllib错误消息()

时间:2015-11-11 21:27:16

标签: python python-3.x error-handling 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.

所以我打算如何使用它,但是当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

2 个答案:

答案 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))

虽然我不确定你应该 - 在一个地方处理错误,例如,重新引用更多特定于应用程序的异常,或者将日志记录留给上游处理程序。