Exceptions prevent all connected receivers from being called.
htoothrot opened this issue · comments
I would like a way of ensuring all receivers are called, even if one misbehaves.
Happy to do a PR if you can give some direction.
Example below (and of course the order of receivers is not specified).
>>> import blinker
... sig = blinker.signal('asignal')
... def a(sender):
... print (sender)
... print ('a done')
... def bad(sender):
... print (sender)
... 1/0
... print ('never done')
... def c(sender):
... print (sender)
... print ('c done')
... sig.connect(a)
... sig.connect(bad)
... sig.connect(c)
... sig.send('THESENDERSTRING')
THESENDERSTRING
a done
THESENDERSTRING
Traceback (most recent call last):
File "<pyshell#2>", line 16, in <module>
sig.send('THESENDERSTRING')
File "D:\Python27\lib\site-packages\blinker\base.py", line 267, in send
for receiver in self.receivers_for(sender)]
File "<pyshell#1>", line 8, in bad
1/0
ZeroDivisionError: integer division or modulo by zero
>>>
This is very simple to implement. However it's notably absent from Blinker, which otherwise mostly follows the Django signal API at the point when Blinker was born. The reason is that I haven't seen a need for this, or an instance when the quashing & reporting adds value to a design vs failing fast. The omission of send_robust
is opinionated design in Blinker.
All that said I'm happy to be shown otherwise, and such a use case could be easily implemented, or at least some refactoring done in the sending code such that a subclass could reasonably implement send_robust
on its own.
My use case is one of plugins. A badly behaving plugin should not be able to interfere with another.
That being said, I simply subclassed NamedSignal
, reimplemented send()
, and then created my own Namespace
class which used my RobustNamedSignal
.