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

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

5 54

5 ответов:

добавить универсальный обработчик исключений:

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())

С документы-страницыurlopen запись, похоже, вам просто нужно ловить URLError. Если вы действительно хотите, чтобы подстраховаться от проблем в коде urllib, вы также можете поймать Exception как запасной вариант. Делай не просто except:, так как это будет ловить SystemExit и KeyboardInterrupt также.

Edit: я хочу сказать, что вы ловите ошибки, которые он должен бросить. Если он бросает что-то еще, это, вероятно, из-за код urllib не ловит то, что он должен был поймать и завернуть в URLError. Даже stdlib имеет тенденцию пропускать простые вещи, такие как AttributeError. Ловлю Exception в качестве отступления (и регистрации того, что он поймал) поможет вам выяснить, что происходит, без захвата SystemExit и KeyboardInterrupt.

$ 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. ключевое эмпирическое правило здесь заключается в никогда не ловите исключения, которые вы не планируете исправлять и регистрация не является коррекцией. так что не ловите их только для регистрации их.

вы можете поймать все исключения и журналов, что поймают:

 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.

Я ловлю:

httplib.HTTPException
urllib2.HTTPError
urllib2.URLError

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