簡體   English   中英

Python 使用過濾回溯引發異常

[英]Python Raising Exception with filtered traceback

我正在嘗試使用不包含最后一幀的堆棧跟蹤引發異常。

在 python 2 中,可以像這樣從 strack 中刪除最后一個條目:

def exceptionCatcher(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception:
            excInfo = sys.exc_info()
            # some custom logging stuff
            raise excInfo[0], excInfo[1], excInfo[2].tb_next
    return wrapper

def a():
    raise Exception("My Exception")

@exceptionCatcher
def test():
    a()

這在 python 中有效,並從回溯中排除了最后一個 exceptionCatcher 調用本身,例如

Traceback (most recent call last):
  File "test.py", line 15, in <module>
    test()
  File "test.py", line 12, in a
    raise Exception("a")
Exception: a 

代替

Traceback (most recent call last):
  File "test.py", line 12, in <module>
    test()
  File "test.py", line 9, in wrapper
    raise e
  File "test.py", line 5, in wrapper
    return func(*args, **kwargs)
  File "test.py", line 10, in test
    a()
  File "test.py", line 5, in a
    raise Exception("a")
Exception: a

切換到 python3 不可能引發異常,例如: raise excInfo[0], excInfo[1], excInfo[2].tb_next

我不得不使用:

def exceptionCatcher(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            excInfo = sys.exc_info()
            # some custom logging stuff
            raise e.with_traceback(excInfo[2].tb_next)
...  

在我的回溯中添加了以下行:

Traceback (most recent call last):
  File "test.py", line 12, in <module>
    test()
  File "test.py", line 9, in wrapper
    raise e.with_traceback(excInfo[2].tb_next)
  File "test.py", line 10, in test
    a()
  File "test.py", line 5, in a
    raise Exception("a")
Exception: a

有什么辦法可以擺脫這部分回溯?

我知道 exceptionCatching 可以用 exceptionhook 完成,但在我使用這個的場景中,不可能使用 exceptionhook,因為它是另一個第三方應用程序(在 cpp 中),它似乎捕獲異常,所以 exceptionhook 不會捕獲任何異常。 所以我想出了使用包裝裝飾器的想法,如上所示,盡管這是一種 hacky 方式。

使用上下文管理器代替裝飾器,它首先不添加堆棧框架。

import contextlib


@contextlib.contextmanager
def exceptionCatcher():
    try:
        yield
    except Exception as e:
        print("custom logging")
        raise


def a():
    raise Exception("My Exception")


def test():
    with exceptionCatcher():
        a()


test()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM