不允许捕获不从 BaseException 继承的 类

catching classes that do not inherit from BaseException is not allowed

我正在制作一个自定义插件来查询数据库中的用户信息以帮助客户支持。我的后端很松弛。

每次我启动机器人命令时,我都会收到:

Computer says nooo. See logs for details:
catching classes that do not inherit from BaseException is not allowed

我不确定这是否是在警告我,我正试图在我的代码中捕获一个不是 BaseClass 的异常,或者是否在我的插件之外的其他地方引发并捕获了一个未知异常。

调试我试过:

try:
    do_the_thing()
except (TypeError, ValueError) as e:
    return('Something went wrong.')

我也试过:

try:
    do_the_thing()
except Exception as e:
    return('Something went wrong.')

而且我仍然收到 errbot 警告。请注意,在 do_the_thing().

没有引发异常的情况下,该命令仍在运行并执行正确的操作

意思是:

  1. 在您的代码中某处有一个 except ... 语句,其中异常 ...(或序列 ... 中的异常之一)不是子 class BaseException
  2. 正在抛出异常,该异常被 except ... 语句捕获。

TypeError 只能在实际抛出异常时引发,因为您给 except ... 的名称必须在当时评估其当前值;仅仅因为 TypeError 在程序执行的某一时刻引用了一个特定的 class 并不意味着它以后不会被更改为引用另一个对象(尽管这被认为是不正当的)。

Python 解释器应该给你一个异常的完整回溯;你需要做的第一件事就是找到这个。它可能发生在两种情况之一。 (这是针对单线程程序的;我假设您的程序不是多线程的。)

  1. 在你的程序执行期间,在这种情况下程序将被异常终止,或者
  2. 在对象完成期间(在它们的 __del__(self) 函数中),在这种情况下,错误将打印到标准错误。

在这两种情况下都应该有堆栈跟踪,而不仅仅是错误消息;我已经确认至少在 Python ≥3.4 时打印了案例 2 的堆栈跟踪。

然后您需要跟踪此堆栈跟踪以查看问题出在哪里。请记住,你给 except ... 的名字是 变量 (甚至像 TypeError 这样的东西)可以重新分配,所以你可以想像地处理一个(反常的) ) 情况如:

TypeError = False
try:
    ...
except TypeError:
    ...

但更有可能是一些显而易见的事情,例如:

class MyException:    # Doesn't inherit from Exception
    ...
try:
    ...
except MyException:
    ...

您需要注意一种特殊情况:如果您在程序退出时看到打印到 stderr 的消息(上面的情况“2. 在完成期间”),这意味着在清理期间抛出了异常当解释器关闭时,作为清理过程的一部分,整个程序中的随机变量可能已经设置为 None。但在这种情况下你的程序应该仍然成功退出。