import asyncio
caught_value_error = False
try:
await async_fail('ValueError', 'test error') assert False, 'should not reach here'
except ValueError:
caught_value_error = True
assert caught_value_error
caught_type_error = False
try:
await async_fail('TypeError', 'type error message') assert False, 'should not reach here'
except TypeError:
caught_type_error = True
assert caught_type_error
caught_key_error = False
try:
await async_fail('KeyError', 'missing key') assert False, 'should not reach here'
except KeyError:
caught_key_error = True
assert caught_key_error
caught_runtime_error = False
try:
await async_fail('RuntimeError', 'runtime error') assert False, 'should not reach here'
except RuntimeError:
caught_runtime_error = True
assert caught_runtime_error
caught_outer = False
try:
try:
await async_fail('ValueError', 'inner error') except TypeError:
assert False, 'TypeError should not catch ValueError'
except ValueError:
caught_outer = True
assert caught_outer
try:
x = 1 + (await async_fail('ValueError', 'mid-expr')) + 2 assert False, 'should not reach here'
except ValueError:
pass
try:
x = (await async_fail('ValueError', 'first')) + add_ints(1, 2) assert False, 'should not reach here'
except ValueError:
pass
finally_ran = False
try:
await async_fail('ValueError', 'in try') except ValueError:
pass finally:
finally_ran = True
assert finally_ran
outer_caught = False
finally_ran2 = False
try:
try:
await async_fail('KeyError', 'will propagate') except ValueError:
assert False, 'ValueError should not catch KeyError'
finally:
finally_ran2 = True
except KeyError:
outer_caught = True
assert finally_ran2
assert outer_caught
value1 = await async_call(30) assert value1 == 30
try:
await async_fail('ValueError', 'after success') assert False, 'should not reach here'
except ValueError:
pass
caught_exc = False
try:
await async_fail('TypeError', 'will be caught') except TypeError:
caught_exc = True
value2 = await async_call(10) assert caught_exc
assert value2 == 10
outer_catch = False
try:
try:
raise ValueError('inner')
except ValueError:
await async_fail('TypeError', 'from handler') except TypeError:
outer_catch = True
assert outer_catch
else_exc_caught = False
try:
try:
pass except:
assert False, 'should not reach except'
else:
await async_fail('RuntimeError', 'from else') except RuntimeError:
else_exc_caught = True
assert else_exc_caught
finally_exc_caught = False
try:
try:
pass
finally:
await async_fail('ValueError', 'from finally') except ValueError:
finally_exc_caught = True
assert finally_exc_caught
inner_handled = False
outer_handled = False
finally_count = 0
try:
try:
await async_fail('ValueError', 'inner error') except ValueError:
inner_handled = True
await async_fail('TypeError', 'from inner handler') finally:
finally_count += 1
except TypeError:
outer_handled = True
finally:
finally_count += 1
assert inner_handled
assert outer_handled
assert finally_count == 2
try:
await async_fail('ValueError', 'exact message') assert False, 'should not reach here'
except ValueError as e:
assert str(e) == 'exact message', f'message preserved through await: {e}'
async def wrapper_rereraise():
try:
await async_fail('ValueError', 're-raised')
except ValueError:
raise
outer_reraised = False
try:
await wrapper_rereraise() except ValueError as e:
assert str(e) == 're-raised'
outer_reraised = True
assert outer_reraised
async def wrapper_catches():
try:
await async_fail('ValueError', 'inside wrapper')
return 'no error'
except ValueError as e:
return 'caught: ' + str(e)
wrapper_result = await wrapper_catches() assert wrapper_result == 'caught: inside wrapper', f'caught inside async wrapper: {wrapper_result}'
async def inner_wrapper():
await async_fail('ValueError', 'deep')
async def outer_wrapper():
await inner_wrapper()
nested_caught = None
try:
await outer_wrapper() except ValueError as e:
nested_caught = str(e)
assert nested_caught == 'deep'
caught_gather = None
try:
await asyncio.gather(async_call(1), async_fail('ValueError', 'gather failure')) except ValueError as e:
caught_gather = str(e)
assert caught_gather == 'gather failure'
async def get_a():
return await async_fail('ValueError', 'async boom')
async def get_b():
return await async_call('b')
gathered_coro_caught = None
try:
await asyncio.gather(get_a(), get_b()) except ValueError as e:
gathered_coro_caught = str(e)
assert gathered_coro_caught == 'async boom', f'gathered child exception caught at gather: {gathered_coro_caught}'
reawait_fail = async_fail('ValueError', 'cached failure')
errors = []
for _ in range(3):
try:
await reawait_fail assert False, 'await of failed future should raise'
except ValueError as e:
errors.append(str(e))
assert errors == ['cached failure', 'cached failure', 'cached failure'], (
f'each re-await of a failed future replays the cached error: {errors}'
)
async def return_await_except():
try:
return await async_fail('ValueError', 'return boom')
except ValueError as e:
return f'caught {e}'
assert await return_await_except() == 'caught return boom'
return_finally_events = []
async def return_await_finally():
try:
return await async_fail('ValueError', 'through finally')
finally:
return_finally_events.append('finally')
try:
await return_await_finally() except ValueError as e:
return_finally_events.append(str(e))
assert return_finally_events == ['finally', 'through finally']