I have a generator that handles data, but may throw an exception. This exception needs to be handled outside the generator, but I would like to resume the generator afterwards. A simple example:
def generator():
yield "some data"
raise ValueError("Something bad happened")
yield "more data"
def use_generator():
gen = generator()
while True:
try:
thing = next(gen)
do_something(thing)
except ValueError:
handle_error()
except StopIteration:
break
def do_something(thing):print(thing)
def handle_error():print("caught ValueError")
The intended output would be something like
some data
caught ValueError
more data
This does not work, because after throwing the exception, any calls to the generator will only raise a StopIteration, so the generator can't be used after the exception. Is there a way to resume function after handling the exception outside?
One way would be to catch the Error inside the generator (I do know where and what type of error are expected) and yield it. Modified, it would look like this:
def generator2():
yield "some data"
try:
raise ValueError("Something bad happnened")
except ValueError as e:
yield e
yield "more data"
def use_generator2():
gen = generator2()
while True:
try:
thing = next(gen)
if isinstance(thing, ValueError):
raise ValueError
do_something(thing)
except ValueError:
handle_error()
except StopIteration:
break
This version produces the expected behavior, though it's also fairly cumbersome. Is there a better way to do things?