Python: eliminating stack traces into library code?

前端 未结 4 757
梦谈多话
梦谈多话 2020-12-10 16:15

When I get a runtime exception from the standard library, it\'s almost always a problem in my code and not in the library code. Is there a way to truncate the exception sta

相关标签:
4条回答
  • 2020-12-10 16:24

    Put an unqualified try...except at the top of your code (ie: in your "main") or set sys.excepthook. You can then format the stack trace however you'd like.

    0 讨论(0)
  • 2020-12-10 16:28

    The traceback module in Python's standard library lets you emit error tracebacks in a way that accords to your liking, while an exception is propagating. You can use this power either in the except leg of a try/except statement, or in a function you've installed as sys.excepthook, which gets called if and when an exception propagates all the way; quoting the docs:

    In an interactive session this happens just before control is returned to the prompt; in a Python program this happens just before the program exits. The handling of such top-level exceptions can be customized by assigning another three-argument function to sys.excepthook.

    Here's a simple, artificial example:

    >>> import sys
    >>> import traceback
    >>> def f(n):
    ...   if n<=0: raise ZeroDivisionError
    ...   f(n-1)
    ... 
    >>> def excepthook(type, value, tb):
    ...   traceback.print_exception(type, value, tb, 3)
    ... 
    >>> sys.excepthook = excepthook
    >>> f(8)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 3, in f
      File "<stdin>", line 3, in f
    ZeroDivisionError
    

    as you see, without needing a try/except, you can easily limit the traceback to (for example) the first three levels -- even though we know by design that there were 9 nested levels when the exception was raised.

    You want something more sophisticated than a simple limit on levels, so you'll need to call traceback.format_exception, which gives you a list of lines rather than printing it, then "prune" from that list the lines that are about modules you never want to see in your tracebacks, and finally emit the remaining lines (typically to sys.stderr, but, whatever!-).

    0 讨论(0)
  • 2020-12-10 16:31

    The Traceback library is probably what you want. Here's one example that might help:

    import traceback
    
    try:
        your_main()
    except:
        lines = traceback.format_exc()
        print lines[:lines.find('File "/usr')]
    

    (This obviously won't work if there's an exception outside the library, and might not exactly fit your needs, but it's one way of using the traceback library)

    0 讨论(0)
  • 2020-12-10 16:37

    Thanks to the pointer from Alex, here's teh codez:

    def trimmedexceptions(type, value, tb, pylibdir=None, lev=None):
        """trim system packages from the exception printout"""
        if pylibdir is None:
            import traceback, distutils.sysconfig
            pylibdir = distutils.sysconfig.get_python_lib(1,1)
            nlev = trimmedexceptions(type, value, tb, pylibdir, 0)
            traceback.print_exception(type, value, tb, nlev)
        else:
            fn = tb.tb_frame.f_code.co_filename
            if tb.tb_next is None or fn.startswith(pylibdir):
                return lev
            else:
                return trimmedexceptions(type, value, tb.tb_next, pylibdir, lev+1)
    
    import sys
    sys.excepthook=trimmedexceptions
    
    # --- test code ---
    
    def f1(): f2()
    def f2(): f3()
    def f3():
        import xmlrpclib
        proxy = xmlrpclib.ServerProxy('http://nosuchserver')
        proxy.f()
    
    f1()
    

    Which yields this stack trace:

    Traceback (most recent call last):
      File "./tsttraceback.py", line 47, in <module>
        f1()
      File "./tsttraceback.py", line 40, in f1
        def f1(): f2()
      File "./tsttraceback.py", line 41, in f2
        def f2(): f3()
      File "./tsttraceback.py", line 45, in f3
        proxy.f()
    gaierror: [Errno -2] Name or service not known
    
    0 讨论(0)
提交回复
热议问题