使用urllib2.Request / urlopen需要处理哪些错误/异常?

时间:2009-03-20 12:56:22

标签: python

我有以下代码来回发远程网址:

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

使用urllib.urlencode编码的字典创建postBackData。 checksLogger是一个使用logging的记录器。

当远程服务器关闭且代码退出时,我遇到了这个代码运行的问题(这是在客户服务器上,所以我不知道此时退出堆栈转储/错误是什么)。我假设这是因为存在未处理的异常和/或错误。那么是否还有其他可能被触发的异常,我上面没有处理过?

5 个答案:

答案 0 :(得分:58)

添加通用异常处理程序:

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

答案 1 :(得分:17)

docs page urlopen条目中,您似乎只需要抓住URLError。如果你真的想在urllib代码中对冲问题,你也可以将Exception作为后备。 只是except:,因为它也会抓住SystemExitKeyboardInterrupt

编辑:我的意思是说,你正在捕捉它应该抛出的错误。如果它正在抛出其他东西,那可能是因为urllib代码没有捕获它应该捕获并包裹在URLError中的东西。甚至stdlib也会错过像AttributeError这样简单的事情。将Exception作为后备(并记录它捕获的内容)将帮助您弄清楚发生了什么,而不会捕获SystemExitKeyboardInterrupt

答案 2 :(得分:15)

$ 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在文件中记录所有未捕获的异常。 这里的关键经验法则是永远不会捕获您不打算纠正的异常记录不是纠正所以不要抓住它们只是为了记录它们。

答案 3 :(得分:1)

您可以捕获所有异常并记录被捕获的内容:

 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的代码)

另请阅读documentation on sys.exc_info

答案 4 :(得分:0)

我抓住了:

httplib.HTTPException
urllib2.HTTPError
urllib2.URLError

我相信这涵盖了包括套接字错误在内的所有内容。