bharal
bharal

Reputation: 16194

If I want to bubble up a generic exception, what do i do in python?

So let's say i have this python code:

def loopForEachFileInDirectory(self, conn):
    for filename in os.listdir(uploadedFilesDirectory):
        try:
            self.insertNewEntryForStagingFile(conn, filename)
            self.copyFilesToStagingDirectory(filename)
        except: ???

def copyFilesToStagingDirectory(self, filename):
    logging.info("copying %s to youtube_ready",filename)
    try:
        shutil.copy(uploadedFilesDirectory+filename, stagingDirectory)
        logging.info("move successful")
    except shutil.Error,e:
        logging.warn("move failed for reasons \n\t%d:%s", e.args[0],e.args[1])
        raise ???

Now, the "loopForEachFileInDirectory" method is going to have a few more methods in it - i'm doing a bit of clean coding (cheers Robert Martin) here. What i'd like is to bubble up any exceptions from the sub-methods, and if anything happens in the main loop, bail on that loop and continue.

The question is, what is the rule for bubbling up a generic exception? Do i just raise on its own? And if so, how do i generically throw an exception, and how do i catch and log the details of a generic exception?

Upvotes: 6

Views: 14489

Answers (3)

Rafał Dowgird
Rafał Dowgird

Reputation: 45131

A short Python 3 extension to what other posters have written. In most cases, the bare raise is enough. It re-raises the original exception which is what you want to do in most cases.

But there are cases when you want to raise a new exception instead - perhaps to add more info to the original one (say the id of the culprit object being processed) or to wrap multiple exception types into one for the convenience of the caller.

In such cases the raise ... from ... (Python 3 only, I'm afraid) construct is useful as in:

try:
    self.file = open(filename)
except IOError, exc:
    raise DatabaseError('failed to open') from exc

The benefit of the from clause is that it preserves the stack trace of the original exception, which would be lost if you just raised a brand new exception.

Proper re-packing of exceptions in Python 2 is harder, there's a good blog post by Ian Bicking covering the topic here: http://blog.ianbicking.org/2007/09/12/re-raising-exceptions/

Upvotes: 10

mvanveen
mvanveen

Reputation: 10028

what is the rule for bubbling up a generic exception? Do i just raise on its own?

Yes. The short answer is to just use raise.

And if so, how do i generically throw an exception...

The above answer the other submitter posted is correct, but it doesn't provide much in the way of context.

Exception is the base class exception. except Exception works across all types of Exception because all Python exceptions inherit from this class.

except statements can specify an argument which points to the the exception object.

I don't believe that specifying it is strictly necessary in this context. In fact, it's likely sufficient to bubble up an exception with the default:

except:
  raise

without any real need to specify an exception type or the variable e referencing the particular exception object.

..and how do i catch and log the details of a generic exception?

logging.exception is a good way to go. Try it like so:

try:
   <something that raises an error>
except Exception, e:
   logging.exception(e)

Upvotes: 16

synthesizerpatel
synthesizerpatel

Reputation: 28036

#!/usr/bin/python

try:
        print 'Youll see me first.'

        try:
                1[90]

        except Exception,e:

                print "************ UTOH!",str(e)
                raise e

except Exception,e:

        print ">>>>>>>>>>>> I concur, THE JIG IS UP!",str(e)
        raise e

Upvotes: 0

Related Questions