import asyncio
from asgiref.sync import sync_to_async
@sync_to_async
def sync_func():
print("sync_func() was CALLED (good!)")
async def async_func():
print("async_func() was CALLED (good!)")
async def test(excep_type: type = asyncio.CancelledError):
print(f"\nException Type: {excep_type}")
try:
raise excep_type
except:
await async_func()
try:
await sync_func()
except asyncio.CancelledError:
print("sync_func() was CANCELLED (bad!)")
asyncio.run(test(excep_type=ValueError))
asyncio.run(test())
Hi there. I have a simple example
test
is an async function which does nothing but raise a provided error type and then await bothasync_func
andsync_func
inside.sync_func
is a synchronous function made asynchronous withsync_to_async
of the asgiref package.
Running this gives the following output:
Exception Type: <class 'ValueError'>
async_func() was CALLED (good!)
sync_func() was CALLED (good!)
Exception Type: <class 'asyncio.exceptions.CancelledError'>
async_func() was CALLED (good!)
sync_func() was CANCELLED (bad!)
In the first case, ValueError
is raised and inside the exception clause, I can await async_func
and sync_func
like normal.
However in the second case, I have behaviour I wouldn't expect. I should be able to await sync_func
like normal, but it instead raises asyncio.CancelledError
as indicated by the printout.
In reality I haven't changed anything between the two calls, except changed the type of error which was originally raised and caught by the exception clause. However the type of raised error seems to have had an effect.
What this means real-world, is that I cannot use an asynchronous function wrapped by sync_to_async
in any clean-up activity of cancelled tasks
It seems this is caused by the sync_to_async
decorator, as async_func
runs fine.
What am I doing wrong?