ThinkGeek
ThinkGeek

Reputation: 5127

Exceptions must derive from BaseException

What am I missing here?

import sys

class MyBaseError(BaseException):
    def __init__(self, message, base_message=None, *args):
        
        self.message = message
        self.base_message = base_message
        super(MyBaseError, self).__init__()
        
        
    def __str__(self):
        if self.base_message is None:
            return self.message
        
        return self.message + " '" + str(self.base_message) + "'"
        
        
class MyError(MyBaseError):
    """
    """
    
class MyTypeError(MyError):
    """
    """

def run_me():
    raise MyTypeError("run_me")
    

def sayonara():
    try:
        run_me()
    except (MyBaseError) as e:
        raise(MyBaseError("unable to run",
                           e,
                           e.args),
                sys.exc_info()[2])
        
sayonara()

Error:

Traceback (most recent call last):
  File "main.py", line 32, in sayonara
    run_me()
  File "main.py", line 27, in run_me
    raise MyTypeError("run_me")
__main__.MyTypeError: run_me

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "main.py", line 42, in <module>
    sayonara()
  File "main.py", line 40, in sayonara
    sys.exc_info()[2])
TypeError: exceptions must derive from BaseException

MyBaseError class is already deriving from BaseException.

Upvotes: 5

Views: 20318

Answers (2)

Shedrack
Shedrack

Reputation: 743

That means you should raise the Exception class or an instance of it. For example

try:
   1 + "String"
except TypeError:
   raise TypeError("unsupported operand type(s) for +: 'int' and 'str'")

Upvotes: 2

gallen
gallen

Reputation: 1292

In your sayonara() function, it seems you are attempting to raise a tuple of exceptions. The problem is that sys.exc_info()[2] is a traceback, and not an exception, which is the cause of your break. I verified this by placing the following line at the top of the exception block:

print(type(sys.exc_info()[2]))

I'm not certain of what you are trying to do for sure, but a working version of sayonara() is as follows:

def sayonara():
    try:
        run_me()
    except (MyBaseError) as e:
        raise MyBaseError("unable to run", e, e.args)

If you want to include the traceback, you'll need to update your custom Error classes to handle that argument being passed through.

Upvotes: 3

Related Questions