This is one of the reasons why Python moved from “yield” to “await” when implementing coroutines. Yield is not really the right metaphor when you have an event loop, since you don’t yield to the entity that closed you, you yield to the event loop.
I would suggest just going with nested try blocks. It’s pretty clear what is going on, although it might not be immediately apparent WHY the code was written this way unless you’re familiar with the problem.
def gen():
try:
yield 'so far so good'
try:
yield 'yay'
finally:
yield 'bye'
except GeneratorExit:
raise
You could probably even write a finalyield decorator to add an outer try: ...except GeneratorExit: raise block to any generator, like: