Поднимите HTTPError с дополнительной информацией - PullRequest
4 голосов
/ 30 мая 2011

Я хочу поймать urllib2.HTTPError с дополнительной информацией, если это 404:

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

но это не работает, потому что init HTTPError принимает несколько аргументов, которые не документированы. Если бы он работал, он бы потерял след и исходное сообщение. Я тоже пробовал

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

но это только что повторно подняло исключение без дополнительной информации. Что мне делать?

Ответы [ 2 ]

8 голосов
/ 30 мая 2011

HTTPError уже содержит всю необходимую вам информацию, вы можете просто перевыполнить ее следующим образом

raise HTTPError(e.url, e.code, "your message.", e.hdrs, e.fp)
5 голосов
/ 30 мая 2011

Вам просто нужно использовать 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

Вы, конечно, можете привести в порядок это с помощью прилагаемой попытки / исключая:

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'}
...