Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 531
bharal Avatar asked Jan 26 '12 07:01

bharal


People also ask

How do you create a generic exception in Python?

You can also provide a generic except clause, which handles any exception. After the except clause(s), you can include an else-clause. The code in the else-block executes if the code in the try: block does not raise an exception. The else-block is a good place for code that does not need the try: block's protection.

How do you catch a general exception in Python?

In Python, exceptions can be handled using a try statement. The critical operation which can raise an exception is placed inside the try clause. The code that handles the exceptions is written in the except clause. We can thus choose what operations to perform once we have caught the exception.

How do I continue a program after an exception in Python?

Perhaps after the first for-loop, add the try/except . Then if an error is raised, it will continue with the next file. This is a perfect example of why you should use a with statement here to open files. When you open the file using open() , but an error is catched, the file will remain open forever.

How do you raise a value error exception in Python?

Here is a simple example to handle ValueError exception using try-except block. import math x = int(input('Please enter a positive number:\n')) try: print(f'Square Root of {x} is {math. sqrt(x)}') except ValueError as ve: print(f'You entered {x}, which is not a positive number.


2 Answers

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)
like image 86
mvanveen Avatar answered Oct 21 '22 03:10

mvanveen


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/

like image 22
Rafał Dowgird Avatar answered Oct 21 '22 05:10

Rafał Dowgird