7

Is there a way to propagate an exception in a try/except block from one except to the next?

I want to catch a specific error and then do a general error handling as well.

"raise" is letting the exception "bubble up" to an outside try/except, but not inside the try/except block that raised the error.

It should be ideally something like this:

import logging

def getList():
    try:
        newList = ["just", "some", "place", "holders"]
        # Maybe from something like: newList = untrustedGetList()

        # Faulty List now throws IndexError
        someitem = newList[100]

        return newList

    except IndexError:
        # For debugging purposes the content of newList should get logged.
        logging.error("IndexError occured with newList containing: \n%s",   str(newList))

    except:
        # General errors should be handled and include the IndexError as well!
        logging.error("A general error occured, substituting newList with backup")
        newList = ["We", "can", "work", "with", "this", "backup"]
        return newList

The problem I have is that when the IndexError gets catched with the first except, my general error handling in the second except block is not applied.

The only workaround I have for now is to include the general error handling code in the first block as well. Even if i wrap it in it's own functionblock it still seems less than elegant...

2
  • you could but your general error handling in a function and then call it both places, slightly more elegant Commented Dec 29, 2016 at 14:14
  • 1
    Impossible (at least in Python): execution cannot jump from one try/except or if/elif/else block to another one. This is like a rail junction: you go at full speed and go either left or right and are unable to move the train to another branch if you have already taken one. Commented Dec 29, 2016 at 14:16

1 Answer 1

6

You have two options:

  • Don't catch IndexError with a dedicated except .. block. You can always test manually for the type of exception in the general block by catching BaseException and assigning the exception to a name (here e):

    try:
        # ...
    except BaseException as e:
        if isinstance(e, IndexError):
            logging.error("IndexError occured with newList containing: \n%s",   str(newList))
    
        logging.error("A general error occured, substituting newList with backup")
        newList = ["We", "can", "work", "with", "this", "backup"]
        return newList
    
  • Use nested try..except statements and re-raise:

    try:
        try:
            # ...
        except IndexError:
            logging.error("IndexError occured with newList containing: \n%s",   str(newList))
            raise
    except:
        logging.error("A general error occured, substituting newList with backup")
        newList = ["We", "can", "work", "with", "this", "backup"]
        return newList
    
Sign up to request clarification or add additional context in comments.

1 Comment

So basically the answer to my question is NO. But at least whe have 3 different workarounds. Thx ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.