【问题标题】:Cannot read urllib error message once it is read()读取 urllib 错误消息后无法读取()
【发布时间】:2016-02-13 02:41:56
【问题描述】:

我的问题是 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

我尝试对 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 一起工作

【问题讨论】:

    标签: python python-3.x error-handling urllib


    【解决方案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')))
    

    【讨论】:

    • 您应该保存resp.read() 的结果,以便将原始字节传回HTTPError,而不是重新编码文本。请参阅上面@jf 的答案。
    • 谢谢@reubano。这样肯定更好。我不明白为什么,起初,当我尝试传入原始字节时,变量msg 将保持为空的bytestring 对象。我一定是做错了什么。我想这就是我解码bytestring的原因。
    【解决方案2】:

    错误对象可能从网络读取。网络不可搜索——一般情况下您无法返回。

    您可以将err 替换为从缓冲区(如io.BytesIO())而不是网络读取的新HTTPError 实例,例如(未测试):

    content = err.read()
    self.log.exception(content)
    raise HTTPError(err.url, err.code, err.reason, err.headers, io.BytesIO(content))
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-12
      • 2017-09-20
      • 2020-08-25
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      相关资源
      最近更新 更多