Exceptions - built-in and home-grown

Heiko Wundram heikowu at ceosg.de
Mon Sep 17 13:42:40 EDT 2001


On Monday 17 September 2001 18:42, you wrote:
> Where can I find a list of all the built-in Python exceptions?

Look at the Python Library Reference (chapter 2.2, I think..., somewhere at 
the beginning).

> Why would I want to define my own exceptions if suitable Python ones
> exist?

You should want to define your own exceptions because Python does not define 
suitable exceptions for returning a certain error condition in your program.

In other words, the answer to your question above is: don't. :)

> Do people do processing in the init routine in their own exceptions?

Yep. I've attached an example of an Exception virtual base class. It is 
derived directly from Python's Base Exception class and uses some __init__ 
magic to log the exceptions to a file, if the user desires this. A derived 
exception only has to overwrite Create() and errormsg(), the rest is done in 
the base object.

Btw: I've put the import statements for the two extra classes that are 
referenced at the back, because otherwise a circular import would take 
place... :)

If you're nterested in the whole project (CGIgen), look for it on 
SourceForge.net.

> Thanks for any insight.

Hope this helps!

-- 
Yours sincerely,

	Heiko Wundram

======

"""CGIgenException.py

This file defines the class that is the base class of all exceptions that are 
used in CGIgen. It is
itself derived from the toplevel Exception class. This Exception class 
enhances the basic Exception
class in that it supports logging the exception to a file, as well as 
catching exceptions that were
the base of this exception.

Copyright (C) 2001 by Heiko Wundram.
All rights reserved."""

import os
import sys
import string
import time
import types
import inspect
import traceback



logfile = None
loglevel = 0



def setlogfile(newlogfile):
    """Sets the logfile that is supposed to be used from now on to 
newlogfile. This file is created,
    if it doesn't exist, and messages will keep being appended to the file as 
they arise. Pass in None
    to stop any logging."""
    global logfile

    logfile = newlogfile

def setloglevel(newloglevel):
    """Sets the loglevel to level. The most severe errors have loglevel 0, 
and decreasing from there."""
    global loglevel

    loglevel = newloglevel

def logmessage(message, severity):
    """Logs the message message to the logfile, in case the severity is less 
than or equal to the
    current loglevel."""
    global logfile
    global loglevel

    if not logfile or severity == -1:
        return

    if severity > loglevel:
        return

    mutex = CGIgen.Base.Mutex.FileMutex(logfile)
    mutex.acquireExclusive()

    try:
        log = open(logfile,"a+")
    except:
        raise CGIgenExceptions.CGIgenLoggingError(0)

    try:
        try:
            log.write(time.asctime()+"\n")
            log.write(message)
            if message[-1] != '\n':
                log.write("\n")
            log.write("\n")
            log.close()
        finally:
            mutex.release()
    except:
        raise CGIgenExceptions.CGIgenLoggingError(0)



class CGIgenException(Exception):
    """This class supports a rich interface to look at exceptions. It can be 
subclassed, but in a
    subclass, only the Create and the errormsg functions should be 
overridden."""

    def __init__(self, severity, *args, **kwargs):
        """Initializes a CGIgenException object and logs it if that is 
wished. The severity parameter
        is always processed by __init__. It decides whether the message is 
logged or not, the
        exception is thrown nevertheless."""

        if sys.exc_info()[0]:
            self.__old_exctype = sys.exc_info()[0]
            self.__old_excvalue = sys.exc_info()[1]
            self.__old_exctraceback = sys.exc_info()[2]
        else:
            self.__old_exctype = None

        self.__severity = severity

        apply(self.Create,args,kwargs)

        self.log()

    def Create(self):
        """This function only serves as the base to a functional create in a 
submodule. That create
        function is passed all the parameters that were given in the call to 
init."""

        raise CGIgenExceptions.CGIgenExceptionError(0)

    def log(self):
        """This function performs all tasks that are necessary to log the 
exception to the logfile, if
        that is wished by the user of CGIgen."""

        message = "Error: "+self.errormsg()[0]+"\n"
        message += str(self)+"\n"

        message += "Raised in:\n"

        message += 
string.join(traceback.format_stack(inspect.getouterframes(inspect.currentframe())[2][0],3))

        if self.__old_exctype:
            message += "\nError was raised due to catching another error.\n"
            if type(self.__old_excvalue) == types.InstanceType and 
isinstance(self.__old_excvalue,CGIgenException):
                message += "Old Error: 
"+self.__old_excvalue.errormsg()[0]+"\n"
                message += str(self.__old_excvalue)+"\n"
            else:
                message += "Old Exception: "+str(self.__old_exctype)+"\n"
                if self.__old_excvalue:
                    message += str(self.__old_excvalue)+"\n"
            message += "Traceback:\n"
            message += 
string.join(traceback.format_tb(self.__old_exctraceback),"")

        logmessage(message,self.__severity)

    def __str__(self):
        """This function returns the string value (error message) of the 
current exception object. It
        uses self.errormsg() to construct the error message."""

        return string.join(self.errormsg()[1:],", ")+"."



import CGIgen.Base.Mutex
import CGIgenExceptions




More information about the Python-list mailing list