Какие ошибки/исключения мне нужно обрабатывать с помощью urllib2.Request/urlopen?
У меня есть следующий код для обратной передачи удаленного URL:
request = urllib2.Request('http://www.example.com', postBackData, { 'User-Agent' : 'My User Agent' })
try:
response = urllib2.urlopen(request)
except urllib2.HTTPError, e:
checksLogger.error('HTTPError = ' + str(e.code))
except urllib2.URLError, e:
checksLogger.error('URLError = ' + str(e.reason))
except httplib.HTTPException, e:
checksLogger.error('HTTPException')
PostBackData создается с использованием словаря, закодированного с использованием urllib.urlencode. checkLogger является регистратором, использующим logging.
У меня возникла проблема, когда этот код запускается, когда удаленный сервер выключен, и код выходит (это на клиентских серверах, поэтому я не знаю, что в этот момент дамп/ошибка стека). Я предполагаю, что это происходит потому, что есть исключение и/или ошибка, которая не обрабатывается. Могут ли быть другие исключения, которые могут быть вызваны, что я не обрабатываю выше?
Ответы
Ответ 1
Добавить общий обработчик исключений:
request = urllib2.Request('http://www.example.com', postBackData, { 'User-Agent' : 'My User Agent' })
try:
response = urllib2.urlopen(request)
except urllib2.HTTPError, e:
checksLogger.error('HTTPError = ' + str(e.code))
except urllib2.URLError, e:
checksLogger.error('URLError = ' + str(e.reason))
except httplib.HTTPException, e:
checksLogger.error('HTTPException')
except Exception:
import traceback
checksLogger.error('generic exception: ' + traceback.format_exc())
Ответ 2
Из docs page urlopen
, похоже, вам просто нужно поймать URLError. Если вы действительно хотите хеджировать свои ставки против проблем в коде urllib, вы также можете поймать Exception
как спад. Сделайте не только except:
, так как это также будет ловить SystemExit
и KeyboardInterrupt
.
Изменить: я хочу сказать, вы поймаете ошибки, которые он должен бросить. Если он бросает что-то еще, это, вероятно, связано с тем, что код urllib не поймал что-то, что он должен был поймать и завернуть в URLError
. Даже stdlib имеет тенденцию пропускать простые вещи, такие как AttributeError
. Ловля Exception
в качестве спада (и регистрации того, что он поймал) поможет вам разобраться, что происходит, не захватывая SystemExit
и KeyboardInterrupt
.
Ответ 3
$ grep "raise" /usr/lib64/python/urllib2.py
IOError); for HTTP errors, raises an HTTPError, which can also be
raise AttributeError, attr
raise ValueError, "unknown url type: %s" % self.__original
# XXX raise an exception if no one else should try to handle
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
perform the redirect. Otherwise, raise HTTPError if no-one
raise HTTPError(req.get_full_url(), code, msg, headers, fp)
raise HTTPError(req.get_full_url(), code,
raise HTTPError(req.get_full_url(), 401, "digest auth failed",
raise ValueError("AbstractDigestAuthHandler doesn't know "
raise URLError('no host given')
raise URLError('no host given')
raise URLError(err)
raise URLError('unknown url type: %s' % type)
raise URLError('file not on local host')
raise IOError, ('ftp error', 'no host given')
raise URLError(msg)
raise IOError, ('ftp error', msg), sys.exc_info()[2]
raise GopherError('no host given')
Существует также возможность исключений из зависимостей urllib2 или исключений, вызванных подлинными ошибками.
Лучше всего регистрировать все неперехваченные исключения в файле через пользовательский sys.excepthook. Основное правило здесь - никогда не перехватывать исключения, которые вы не планируете исправлять, а протоколирование не является коррекцией. Так что не поймайте их, чтобы зарегистрировать их.
Ответ 4
Вы можете поймать все исключения и записать, что попало:
import sys
import traceback
def formatExceptionInfo(maxTBlevel=5):
cla, exc, trbk = sys.exc_info()
excName = cla.__name__
try:
excArgs = exc.__dict__["args"]
except KeyError:
excArgs = "<no args>"
excTb = traceback.format_tb(trbk, maxTBlevel)
return (excName, excArgs, excTb)
try:
x = x + 1
except:
print formatExceptionInfo()
(Код из http://www.linuxjournal.com/article/5821)
Также читайте документацию по sys.exc_info.
Ответ 5
Я поймаю:
httplib.HTTPException
urllib2.HTTPError
urllib2.URLError
Я считаю, что это охватывает все, включая ошибки сокета.