0

Suppose I have 2 exceptions:

class FooError (Exception): def __init__(self, *args, **kwargs): default_message = 'A foo error has occurred!' if not (args or kwargs): args = (default_message,) super().__init__(*args, **kwargs) class BarError (Exception): def __init__(self, *args, **kwargs): default_message = 'A bar error has occurred!' if not (args or kwargs): args = (default_message,) super().__init__(*args, **kwargs) 

And, I have a function which throws FooError:

def foobar (x): if x < 0: raise FooError() 

Generally, you would handle FooError with a try/except block:

try: foobar(-1) except FooError: print('Uh oh, foo error!') sys.exit() 

However, I would like to throw a BarError which I can handle later. Something like this:

except BarError: print('Uh oh, bar error!') sys.exit() 

When executing this, though, I just get the traceback of both errors:

Traceback (most recent call last): File "C:\Users\Maze\Desktop\test2.py", line 17, in <module> foobar(-1) File "C:\Users\Maze\Desktop\test2.py", line 15, in foobar raise FooError() __main__.FooError: A foo error has occurred! During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\Maze\Desktop\test2.py", line 19, in <module> raise BarError() __main__.BarError: A bar error has occurred! 

How do I throw BarError inside of the handler for FooError, and then handle BarError in a different except block?

3 Answers 3

2

You can't. Once you've caught an exception, you can't transfer control to another except block in the same try statement. You can use a nested statement:

try: try: foobar(-1) except FooError: raise BarError except BarError: print('Uh oh, bar error!') sys.exit() 

Some additional work is necessary if you want to distinguish between BarErrors raised directly by foobar and the BarError raised as a result of the FooError being caught. You can use exception chaining for this. See PEP-3134 for more details; this example may not be the best way to write this.

try: try: foobar(-1) except FooError as exc: raise BarError from exc except BarError as exc: if isinstance(exc.__cause__, FooError): print("Caught a Foo-induced BarError") else: print("Caught a regular BarError") 
Sign up to request clarification or add additional context in comments.

Comments

1

Not sure whether I understood what you were asking, but you can easily raise new exceptions in other exception handlers:

def call_foobar(): try: foobar(-1) except FooError: print('Uh oh, foo error!') raise BarError() try: call_foobar() except BarError as e: print("Bar Error") 

You don't necessarily need a function for this, nesting two try blocks would be possible as well.

Does this answer your question?

Comments

0

It sounds like you want to catch a FooError or BarError, but you want to do a little extra work first if it is a FooError. If that's the case, you can catch both kinds of exception and only do the work for a FooError:

try: foobar(-1) except (FooError, BarError) as e: if isinstance(e, FooError): # do extra work # Handle errors 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.