使用额外信息重新引发HTTPError

5

如果是404错误,我希望能够捕获urllib2.HTTPError并获取额外信息:

try:
    data = urlopen(url)
except HTTPError, e:  # Python 2.5 syntax
    if e.code == 404:
        raise HTTPError('data not found on remote')
    else:
        raise

但这种方法行不通,因为HTTPError的初始化需要多个参数,并且这些参数没有文档记录。如果真的这样做了,会失去回溯和原始信息。我也尝试过其他方法。

if e.code == 404:
    e.message = 'data not found on remote: %s' % e.message
raise

但是这样做只会重新引发异常,没有额外的信息。我该怎么办?

2个回答

11

HTTPError已经包含了您所需的所有信息,您可以像这样简单地重新引发它

raise HTTPError(e.url, e.code, "your message.", e.hdrs, e.fp)

好的,但现在我仍然失去了回溯信息。我该如何保留它? - Fred Foo
当你重新引发异常时,而不仅仅是使用 raise,请尝试使用 raise e - Jakob Bowyer
5
你能回答我一个更加一般性的问题吗?我第一次使用Python,当我尝试查找HttpError的构造函数参数时,你在这里提供的答案出现了。你是从哪里找到该构造函数的文档的呢?我只能找到官方文档 https://docs.python.org/2/library/urllib2.html#urllib2.HTTPError,但那并没有提供实质性的信息。我注意到很多Python文档都不显示构造函数参数或数据成员,这是我从其他语言中习惯的东西。是我做错了吗? - Steve Broberg
@SteveBroberg 你可以在这里找到参数 http://epydoc.sourceforge.net/stdlib/urllib2.HTTPError-class.html - Mahmoud Akl

5

你只需使用 e.msg 而不是 e.message。以下是脚本示例:

from urllib2 import urlopen, HTTPError

url = 'http://www.red-dove.com/frob'

try:
    data = urlopen(url)
except HTTPError, e:  # Python 2.5 syntax
    if e.code == 404:
        e.msg = 'data not found on remote: %s' % e.msg
    raise

打印

Traceback (most recent call last):
  File "c:\temp\test404.py", line 6, in <module>
    data = urlopen(url)
  File "C:\Python\Lib\urllib2.py", line 124, in urlopen
    return _opener.open(url, data)
  File "C:\Python\Lib\urllib2.py", line 387, in open
    response = meth(req, response)
  File "C:\Python\Lib\urllib2.py", line 498, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python\Lib\urllib2.py", line 425, in error
    return self._call_chain(*args)
  File "C:\Python\Lib\urllib2.py", line 360, in _call_chain
    result = func(*args)
  File "C:\Python\Lib\urllib2.py", line 506, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 404: data not found on remote: Not Found

当然,您可以使用try/except语句来精简代码:

from urllib2 import urlopen, HTTPError

url = 'http://www.red-dove.com/frob'

try:
    try:
        data = urlopen(url)
    except HTTPError, e:  # Python 2.5 syntax
        if e.code == 404:
            e.msg = 'data not found on remote: %s' % e.msg
        raise
except HTTPError, e:
    print e

这将简单打印

HTTP Error 404: data not found on remote: Not Found

异常中包含所有的原始细节:e.__dict__ 的内容如下:
{'__iter__': <bound method _fileobject.__iter__ of <socket._fileobject object at   0x00AF2EF0>>,
 'code': 404,
 'fileno': <bound method _fileobject.fileno of <socket._fileobject object at 0x00AF2EF0>>,
 'fp': <addinfourl at 12003088 whose fp = <socket._fileobject object at 0x00AF2EF0>>,
 'hdrs': <httplib.HTTPMessage instance at 0x00B727B0>,
 'headers': <httplib.HTTPMessage instance at 0x00B727B0>,
 'msg': 'data not found on remote: Not Found',
 'next': <bound method _fileobject.next of <socket._fileobject object at 0x00AF2EF0>>,
 'read': <bound method _fileobject.read of <socket._fileobject object at 0x00AF2EF0>>,
 'readline': <bound method _fileobject.readline of <socket._fileobject object at 0x00AF2EF0>>,
 'readlines': <bound method _fileobject.readlines of <socket._fileobject object at 0x00AF2EF0>>,
 'url': 'http://www.red-dove.com/frob'}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接