Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way of defining exception class hierarchy in python?

i want to be able to raise exception like the built-in ones, you can either pass a message along with it, or just raise the class name(instance created implicitly). like this

raise IndexError

raise IndexError('Something went wrong, bro')

is my following code correct ?

initially i'm thinking about this:

class SomeError(Exception):
    def __init__(self, *args):
        if args:
            print ' '.join(args)

class SomeCriticalError(SomeError):
    def __init__(self, *args):
        super(SomeCriticalError,self).__init__(*args)
        print 'This is a critical error, process stopped ...'
        sys.exit(1)

class SomeCookiesError(SomeCriticalError):
    def __init__(self, *args):
        print 'Firefox cookies retrieving failed ..'   
        super(SomeCookiesError,self).__init__(*args)

but in this case, i have to define __init__() for every subclass of CmiCriticalError, i felt something must be wrong ( calling super() in each subclass seems awkward ), then i tried this

class SomeError(Exception):
    def __init__(self, *args):
        if args:
            print ' '.join(args)
        else:
            print self

class SomeCriticalError(SomeError):
    def __init__(self, *args):
        super(SomeCriticalError,self).__init__(*args)
        print 'This is a critical error, process stopped ...'
        sys.exit(1)

class SomeCookiesError(SomeCriticalError):
    def __str__(self):
        return 'Firefox cookies retrieving failed ..'

but this still feels awkward, what am i missing ?

basically what i want to do is handle exception in the exception instance itself, like the sys.exit() in SomeCriticalError, and because in my main code, i may raise SomeCookiesError at multiple places, i don't want to pass the same message string argument each time, so can i do what the built in exceptions do ? ( when no argument is passed, print default message )

like image 846
Shuman Avatar asked Dec 18 '25 01:12

Shuman


1 Answers

Generally an Exception subclass isn't responsible for dealing with the problem that lead to it being raised. That's up to the error handling code (e.g. the try/catch statements that are wrapped around the place where the exception was raised). The exception type should probably limit itself to presenting a nice message, and encapsulating any appropriate data.

So, in your example, you should deal with "critical" errors simply by not catching them (or only catching them at the very top level, before quitting). Many exception classes can be trivial:

class SomeCriticalError(Exception):
    pass

Some other exception classes might do a bit more, but they should be focused on documenting the appropriate details of the situation, rather than how it is resolved:

class CookieError(Exception):
    def __init__(self, cookie_name):
        super(CookiesError, self).__init__("Could not find Firefox cookie {!r}"
                                           .format(cookie_name)) # custom message

If for debugging a CookieError you needed some extra data, you could have your exception class save it to self.data or whatever (though if you want the raise CookieError syntax to work you need to make all the arguments to the __init__ method optional).

like image 139
Blckknght Avatar answered Dec 20 '25 14:12

Blckknght