Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 'except' fall-through

I was wondering if you could re-raise a (specific) caught exception and have it caught by a later (general) except in the same try-except. As an example, I want to do something with a specific IOError, but if its not the expected IOError then the exception should be handled like any other error. What I initially tried:

try:
    raise IOError()
except IOError as ioerr:
    if ioerr.errno == errno.ENOENT:
        # do something with the expected err
    else:
        # continue with the try-except - should be handled like any other error
        raise
except Exception as ex:
    # general error handling code

However, this doesn't work: the raise re-raises the exception outside the context of the try-except. What would be the pythonic way of writing this to get the desired exception 'fall-through' behaviour?

(I'm aware there was a proposed 'conditional except' that wasn't implemented, which could've solved this)

like image 694
Paradise Avatar asked Oct 19 '15 14:10

Paradise


People also ask

How do I get exception details in Python?

Catching Exceptions 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.

Is there an Except function in Python?

The try block lets you test a block of code for errors. The except block lets you handle the error. The else block lets you execute code when there is no error.

Why does Python use except instead of catch?

In Python programming, exception handling allows a programmer to enable flow control. And it has no. of built-in exceptions to catch errors in case your code breaks. Using try-except is the most common and natural way of handling unexpected errors along with many more exception handling constructs.

What is exception handling Python?

In general, when a Python script encounters a situation that it cannot cope with, it raises an exception. An exception is a Python object that represents an error. When a Python script raises an exception, it must either handle the exception immediately otherwise it terminates and quits.


2 Answers

If you ultimately want it to catch everything, make it do that. Catch first, sieve later. ;)

try:
    raise IOError()
except Exception as ex:
    if isinstance(ex, IOError) and ex.errno == errno.ENOENT:
        # do something with the expected err
    # do the rest
like image 147
Bachsau Avatar answered Sep 20 '22 17:09

Bachsau


I am not an expert in writing pythonically, but I think one obvious approach (if you know that you're expecting one particular kind of exception), would be to use nested exception handling:

try:
    try:
        raise IOError()
    except IOError as ioerr:
        if ioerr.errno == errno.ENOENT:
            # do something with the expected err
        else:
            # pass this on to higher up exception handling
            raise

except Exception as ex:
    # general error handling code

I know in your comment that you didn't want nested else's -- I don't know if nested exception handling is as bad in your book, but at the very least you can avoid code duplication.

like image 26
tobylaroni Avatar answered Sep 17 '22 17:09

tobylaroni