简体   繁体   English

当我不处理异常时如何打印异常?

[英]How to print an exception when I'm not handling it?

I have the following code: 我有以下代码:

# exc is a local variable of type Exception
# This is not inside an except block
if isinstance(exc, ClientError):
    logging.debug("ClientError raised while loading %s:\n%s", package.id, traceback.format_exc())
    continue

When this code is run and exc is of type ClientError , format_exc() just prints out NoneType: None because no exception is currently being handled (the code is not inside an except block). 当这个代码运行和exc是类型的ClientErrorformat_exc()仅仅打印出NoneType: None因为没有异常被当前正在处理(代码不是内部的except块)。 Luckily there appears to be the format_exception method on traceback that isn't coupled to whatever the current exception being handled is, but in order to call it I need to extract the type, values, and tb from my exception variable. 幸运的是,有似乎是format_exception的方法traceback未连接到任何正在处理的当前异常,但为了调用它,我需要提取我的异常变量的类型,价值观和结核病。 How do I do this? 我该怎么做呢?

How is exc being produced? exc是如何产生的? If it is being returned from some function without the corresponding stack then it is not possible to produce the correct frames anyway. 如果它是从某个函数返回而没有相应的堆栈,则无论如何都无法生成正确的帧。 On top of that, it is not possible to generate a Traceback object without going deep into ctypes , so this is likely not what is desired. 最重要的是,如果不深入ctypes ,就不可能生成Traceback对象,因此这可能不是所希望的。

If what you are after is actually the stack at where the exception was logged, making use of inspect.currentframe and traceback.format_stack may produce what you might be after. 如果您所追求的实际上是记录异常的堆栈,那么使用inspect.currentframetraceback.format_stack可能会产生您所追求的。 However, as mentioned, you will need to get the frames as close to where the error occurred. 但是,如前所述,您将需要使帧尽可能靠近发生错误的位置。 Consider this example: 考虑以下示例:

import traceback
import inspect
import logging


class Client:
    pass


class ClientError(Exception):
    pass


def get_client(name):
    if name is None:
        return ClientError('client must have a name')
    return Client()


def connect(target, name=None):
    exc = get_client(name)
    if isinstance(exc, ClientError):
        frames = inspect.currentframe()
        logging.debug("ClientError raised while loading %s:\n%s",
            target, ''.join(traceback.format_stack(frames)))


def main():
    connect('somewhere')


if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    main()

Executing this will produce the following output: 执行此操作将产生以下输出:

DEBUG:root:ClientError raised while loading somewhere:
  File "foo.py", line 34, in <module>
    main()
  File "foo.py", line 30, in main
    connect('somewhere')
  File "foo.py", line 26, in connect
    target, ''.join(traceback.format_stack(frames)))

Note that the stack ends exactly where the call is done, as the return value of the current_frame is bounded to frames . 请注意,由于current_frame的返回值限制为frames ,因此堆栈恰好在调用完成的地方结束。 This is why the stack should be generated and formatted at where it was produced, and step back one level. 这就是为什么应该在堆栈的生成位置对其进行格式化并使其后退一步的原因。 Consider these updated functions: 考虑以下更新的功能:

def get_client(name):
    if name is None:
        return (
            ClientError('client must have a name'),
            traceback.format_stack(inspect.currentframe().f_back),
        )
    return Client(), None


def connect(target, name=None):
    exc, frames = get_client(name)
    if isinstance(exc, ClientError):
        stack = ''.join(frames)
        logging.debug("ClientError raised while loading %s:\n%s",
            target, stack)

Execution 执行

$ python foo.py 
DEBUG:root:ClientError raised while loading somewhere:
  File "foo.py", line 37, in <module>
    main()
  File "foo.py", line 33, in main
    connect('somewhere')
  File "foo.py", line 25, in connect
    exc, frames = get_client(name)

Note how the trace ends at the function that produced the exception. 注意跟踪如何在产生异常的函数处结束。

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

相关问题 当我捕获异常时,如何只打印异常而不打印完整的回溯? - When I catch an exception, how to print only the exception and not the full traceback? 如何使用 python zeep 进行重试处理? 我正在使用请求重试 session,但未处理异常 - How do I get retry handling with python zeep? I'm using a requests retry session, but the exception is not handled 如何使用异常处理在python中打印指定索引中的数字是正数还是负数? - How can I print whether the number in the specified index is positive or negative in python using exception handling? 通过这种简单的异常处理,我应该在哪里打印输出?(Python) - Where should I print my output at this simple exception handling?(Python) 如何在异常处理{except block}中修复打印语句? - how to fix print statement in exception handling{except block}? 解析JSON时出现异常 - I'm getting an exception when parsing JSON 停止程序时是否抛出异常? - Is an exception thrown when I'm stopping the program? 如果代码错误,如何打印异常? - How do I print an exception if error in code? 如何在 Python 中打印异常? - How do I print an exception in Python? 异常处理打印语句不起作用,但错误类型是? - Exception handling print statements not working, but error types are?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM