0

I am catching two exceptions in Python in such way:

#ex1
try: 
    #some code
except:
    #some code to e.g. print str

#ex2
try: 
    #some code
except: 
    #some code to e.g. print str or exit from the program.

if ex1 raises an exception then I want to skip ex2. if ex1 does not raise an exception the I want to try ex2.

What is the most elegant way to code it?

My current approach is to wrap it in a function block as below and use return in right place:

def myExceptions(someArgs):
    #ex1
    try: 
        #some code
    except:
        #some code
        return

    #ex2
    try: 
        #some code
    except: 
        #some code

and then I just call the function in right place myExceptions(someArgs)

6
  • You can have multiple except: clauses for different exceptions for the same try block, there's no need for all these shenanigans. See docs.python.org/3/tutorial/errors.html Commented May 2, 2017 at 22:30
  • Possible duplicate of Catch multiple exceptions in one line (except block) Commented May 2, 2017 at 22:34
  • Also, "using a bare except: is almost never a good idea". Commented May 2, 2017 at 22:36
  • Both try blocks do not have the same code hence why two separate try block with once excepction each. Commented May 2, 2017 at 22:42
  • I feel like his question includes the answer to your question as an example. Commented May 2, 2017 at 22:44

3 Answers 3

2

EDIT: This will work as you described:

try:
    msg = make_msg_fancy(msg)
    msg = check_for_spam(msg)
except MessageNotFancyException:
    print("couldn't make it fancy :(")
except MessageFullOfSpamException:
    print("too much spam :(")

When an exception occurs, it skips the rest of the try block and continues at the exception... it doesn't go back.


You are doing something like this:

for person in [{"dog": "Henry"}, {}, {"dog": None}]:
    try:
        doggo = person['dog']  # can throw KeyError
    except KeyError:
        print("Not a dog person")
        continue  # skip the rest of the loop (since this is a for loop)

    try:
        print(doggo.upper())  # can throw AttributeError
    except AttributeError:
        print("No doggo :(")

A better way is, as Christian suggested:

for person in [{"dog": "Henry"}, {}, {"dog": None}]:
    try:
        doggo = person['dog']  # can throw KeyError
        print(doggo.upper())  # can throw AttributeError
    except KeyError:  # person dict does not contain a "dog"
        print("Not a dog person")
    except AttributeError:  # dog entry cannot be .upper()'d
        print("invalid doggo :(")

Both of which output:

HENRY
Not a dog person
invalid doggo :(

Note this will skip the second set of lines automatically if the first set fails, and lets you do different things based upon which exception occurred.

I think you're confused. After a KeyError above, execution continues after the except blocks. The rest of the try: is skipped, which is what you seem to want:

That's why I can do:

try:
    dct[key] += value
    print("Added.")
except KeyError:
    dct[key] = value
    print("New key.")

Only one of those prints will happen.

Sign up to request clarification or add additional context in comments.

3 Comments

I do as follows: for person in [...]: try: run a function with msg as an input and if function errors then raise user defined exception. next below I do another try: run another function with msg as an input and if function errors then raise user defined exception. If first try raises an exception then do not execute 2nd try block. if 1st try block does not raise an exception then do execute 2nd try block. Does it sound similar to what you have described?
@bluedog update your question if you want to add more detail
@BlueDog this will work for you if you implement it as we've said.
1

Python allows you to use multiple exception clause in your try/except statements. Add all of your code from the two try blocks into one, and simply use two except clause to catch both potentially errors:

try: 
    #some code
except:
    #some code to e.g. print str
except: 
    #some code to e.g. print str or exit from the program.

8 Comments

I raise two separate exceptions for two separate try block because both try blocks have different code. So I do not raise two various exceptions for same try block as per your example.
@BlueDog You don't need to separate try blocks. If you want to skip all the code on the first exception, there is no reason to have two blocks.
@BlueDog but that will happen by itself. When the exception is thrown, controls passes to the relevant exception handler, skipping remaining statements in the try block. If a statement in the try block doesn't raise an exception, execution simply continues.
@BlueDog What does 'ex1 try block exceptions' mean? If ex1 throws an exception, the exception handler runs and statements between the exception handler and the throw location are simply skipped. It makes no difference what the exception handler actually does
@BlueDog oh and if you think the handlers will somehow be executed in sequence, no that is not the case. no matter what the individual handler does, only one handler will be called. You don't just drop down and start executing the next one. I think you should just try some of the examples people have posted for yourself. At this point you seem to be trying to explain to us that Python works the way you've misunderstood it to work.
|
-1

How about this? However, in you should usually be more specific with exceptions, see here: https://docs.python.org/3/tutorial/errors.html for example, use "except ValueError" to only except that one type of error.

try:
    # ex1 code
except:
    # handle the exception
else:
    # ex2 code, will only run if there is no exception in ex1

2 Comments

This looks like the most reasonable answer to me. This is what I thought originaly but I do not know what is better: such way od coding or wrapping all in one function block.
This isn't equivalent since it never handles exceptions raised by the 'ex2 code'.

Your Answer

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