Подтвердить что ты не робот

Какие ошибки/исключения мне нужно обрабатывать с помощью 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.

У меня возникла проблема, когда этот код запускается, когда удаленный сервер выключен, и код выходит (это на клиентских серверах, поэтому я не знаю, что в этот момент дамп/ошибка стека). Я предполагаю, что это происходит потому, что есть исключение и/или ошибка, которая не обрабатывается. Могут ли быть другие исключения, которые могут быть вызваны, что я не обрабатываю выше?

4b9b3361

Ответ 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


Я считаю, что это охватывает все, включая ошибки сокета.