Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

catching classes that do not inherit from BaseException is not allowed

I'm making a custom plugin to query a database for user info to aide customer support. My backend is slack.

Everytime I start the bot command I'm greeted with:

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

I'm not sure if this is warning me that I'm attempting to catch an exception that isn't a BaseClass in my code or if an unknown exception was raised and caught elsewhere outside of my plugin.

To debug I tried:

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

I also tried:

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

And I still get the errbot admonition. Note that the command still runs and does the right thing where there is no exception raised by do_the_thing().

like image 766
Dan Garthwaite Avatar asked Oct 17 '22 06:10

Dan Garthwaite


1 Answers

It means that:

  1. Somewhere in your code you have an except ... statement where the exception ... (or one of the exceptions in the sequence ...) is not a subclass of BaseException, and
  2. An exception is being thrown that is caught by that except ... statement.

The TypeError can be raised only when an exception is actually thrown because the names you give to except ... must be evaluated for their current values at that time; just because TypeError referenced a particular class at one point in the program's execution doesn't mean it won't be changed later to reference another object (though that would be admittedly perverse).

The Python interpreter should be giving you a full traceback of the exception; the first thing you need to do is find this. It could be occurring in one of two situations. (This is for single-threaded programs; I'm assuming your program is not multithreaded.)

  1. During the execution of your program, in which case the program will be terminated by the exception, or
  2. During finalization of objects (in their __del__(self) functions) in which case the error will be printed to stderr.

In both cases there should be a stack trace, not just the error message; I've confirmed that at least on Python ≥3.4 a stack trace is printed out for case 2.

You then need to follow this stack trace to see where the problem lies. Remember that the names you give to except ... are variables (even things like TypeError) that can be reassigned, so that you could conceivably be dealing with a (perverse) situation like:

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

But more likely it will be something obvious such as:

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

There is one special case you need to be aware of: if you are seeing messages to stderr (case "2. During finalization," above) printed out as your program exits that means that the exception was thrown during cleanup as the interpreter shuts down, where random variables throughout the program may have already been set to None as part of the cleanup process. But in this case your program should still exit successfully.

like image 195
cjs Avatar answered Oct 21 '22 08:10

cjs