简体   繁体   English

处理Python中其他库导入的库中的异常的最佳实践?

[英]Best practice for handling exceptions from libraries imported by other libraries in Python?

What is the appropriate way for handling exceptions from libraries imported by other libraries in Python? 在Python中处理其他库导入的库中的异常的合适方法是什么?

For example, I have a library called "pycontrol" that I import into my main program. 例如,我有一个名为“ pycontrol”的库,我将其导入到主程序中。 "pycontrol" imports the "suds" library. “ pycontrol”导入“ suds”库。 The "suds" library, in turn, imports the "urllib2" library. 反过来,“ suds”库导入“ urllib2”库。 I've noticed that when the "suds" library has trouble connecting to remote resources it is accessing through "urllib2," these exceptions trickle up to my main program. 我注意到,当“ suds”库无法连接到通过“ urllib2”访问的远程资源时,这些异常会滴加到我的主程序中。

My best guess at this point is to import urllib2 and suds into my global name space and catch typical exceptions that get thrown by them and aren't handled in "pycontrol". 在这一点上,我最好的猜测是将urllib2和suds导入到我的全局名称空间中,并捕获由它们抛出并且在“ pycontrol”中未处理的典型异常。

Is there some other best practice as to how one might approach this? 还有其他一些最佳实践来解决这一问题吗?

A basic idea of what the snippet of code looks like (without importing suds or urllib2 into global name space): 代码段的基本概念(无需将suds或urllib2导入全局名称空间):

    import pycontrol.pycontrol as pc

    print "Connecting to iControl API on LTM %s..." % ltm
    try:
        b = pc.BIGIP(hostname=ltm, username=user, password=pw, 
            wsdls=wsdl_list, fromurl=True,
            debug=soap_debug)
    except (<whattocatch>), detail:
        print "Error: could not connect to iControl API on LTM %s... aborting!" % ltm
        print "Details: %s" % detail
        exitcode = 1
    else:
        print "Connection successfully established."

Here's a sample traceback: 这是示例追溯:

Connecting to iControl API on LTM s0-bigip1-lb2.lab.zynga.com...
Traceback (most recent call last):
  File "./register.py", line 507, in <module>
    main()
  File "./register.py", line 415, in main
    b = build_bigip_object(ltm, user, pw, WSDLS, soap_debug = False)
  File "./register.py", line 85, in build_bigip_object
    debug=soap_debug)
  File "build/bdist.macosx-10.6-universal/egg/pycontrol/pycontrol.py", line 81, in __init__
  File "build/bdist.macosx-10.6-universal/egg/pycontrol/pycontrol.py", line 103, in _get_clients
  File "build/bdist.macosx-10.6-universal/egg/pycontrol/pycontrol.py", line 149, in _get_suds_client
  File "/Library/Python/2.6/site-packages/suds/client.py", line 111, in __init__
    self.wsdl = reader.open(url)
  File "/Library/Python/2.6/site-packages/suds/reader.py", line 136, in open
    d = self.fn(url, self.options)
  File "/Library/Python/2.6/site-packages/suds/wsdl.py", line 136, in __init__
    d = reader.open(url)
  File "/Library/Python/2.6/site-packages/suds/reader.py", line 73, in open
    d = self.download(url)
  File "/Library/Python/2.6/site-packages/suds/reader.py", line 88, in download
    fp = self.options.transport.open(Request(url))
  File "/Library/Python/2.6/site-packages/suds/transport/https.py", line 60, in open
    return  HttpTransport.open(self, request)
  File "/Library/Python/2.6/site-packages/suds/transport/http.py", line 62, in open
    return self.u2open(u2request)
  File "/Library/Python/2.6/site-packages/suds/transport/http.py", line 118, in u2open
    return url.open(u2request, timeout=tm)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 383, in open
    response = self._open(req, data)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 401, in _open
    '_open', req)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 361, in _call_chain
    result = func(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 1138, in https_open
    return self.do_open(httplib.HTTPSConnection, req)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 1105, in do_open
    raise URLError(err)
urllib2.URLError: <urlopen error [Errno 8] nodename nor servname provided, or not known>

I think you answered you question yourself. 我想你回答了你自己的问题。 Import urllib2 and catch the exception in your module. 导入urllib2并在模块中捕获异常。

from urllib2 import URLError

try:
    # something
except URLError, e:
    # Do something in case of error.

Why do you need to catch specific exceptions at all? 为什么您需要完全捕获特定的异常? After all, any exception (not only URLError ) raised from b = pc.BIGIP(...) means you cannot go on. 毕竟,从b = pc.BIGIP(...)引发的任何异常(不仅是URLError b = pc.BIGIP(...)意味着您无法继续。

I suggest: 我建议:

import traceback

try:
    b = pc.BIGIP(...)
except:
    traceback.print_exc()
    exitcode = 1
else:
    do_something_with_connection(b)

Another idea: Why bother with catching the exception at all? 另一个想法:为什么要费心去捕捉异常? The Python interpreter will dump a stack trace to stderr and exit the program when it encounters an unhandled exception: Python解释器会将堆栈跟踪信息转储到stderr,并在遇到未处理的异常时退出程序:

b = bc.BIGIP(...)
do_something_with_connection(b)

Or if you need to write to an error log: 或者,如果您需要写入错误日志:

import logging
import sys

def main():
   b = bc.BIGIP(...)
   do_something_with_connection(b)

if __name__ == "__main__":
    try:
        main()
    except:
        logging.exception("An unexpected error occured")
        sys.exit(1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM