python / expert
Snippet
Isolated Exception Handling in Asynchronous Signal Handlers
Extending Django Signal dispatching allows executing async and sync subscribers safely within event loops while isolating exceptions per receiver to prevent signal cascading failures.
snippet.py
python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import asynciofrom typing import Any, Callable, Listfrom asgiref.sync import sync_to_asyncfrom django.dispatch import Signalclass AsyncIsolatedSignal(Signal):async def send_robust_async(self, sender: Any, **named: Any) -> List[tuple[Callable, Any]]:responses = []for receiver in self._live_receivers(sender):try:if asyncio.iscoroutinefunction(receiver):res = await receiver(sender=sender, **named)else:res = await sync_to_async(receiver, thread_sensitive=True)(sender=sender, **named)responses.append((receiver, res))except Exception as err:responses.append((receiver, err))return responses
django
Breakdown
1
class AsyncIsolatedSignal(Signal):
Custom Signal subclass providing asynchronous execution capabilities.
2
async def send_robust_async(self, sender: Any, **named: Any):
Asynchronous dispatch method iterating over registered signal receivers.
3
res = await sync_to_async(receiver, thread_sensitive=True)(...)
Wraps traditional synchronous receivers into thread-sensitive async coroutines.
4
except Exception as err:
Catches individual receiver errors without aborting execution for remaining receivers.