irclib: Catch exception from outFilter, as with inFilter

This commit is contained in:
Valentin Lorentz 2022-03-17 22:29:10 +01:00
parent 862fca1602
commit 088d0f54dd
2 changed files with 45 additions and 1 deletions

View File

@ -1527,7 +1527,11 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
msg._len = msg._str = None msg._len = msg._str = None
for callback in reversed(self.callbacks): for callback in reversed(self.callbacks):
self._setMsgChannel(msg) self._setMsgChannel(msg)
msg = callback.outFilter(self, msg) try:
msg = callback.outFilter(self, msg)
except:
log.exception('Uncaught exception in outFilter:')
continue
if msg is None: if msg is None:
log.debug('%s.outFilter returned None.', callback.name()) log.debug('%s.outFilter returned None.', callback.name())
return self.takeMsg() return self.takeMsg()

View File

@ -1023,6 +1023,46 @@ class IrcTestCase(SupyTestCase):
self.irc.feedMsg(ircmsgs.IrcMsg('MODE @#linux3 +v foo')) self.irc.feedMsg(ircmsgs.IrcMsg('MODE @#linux3 +v foo'))
self.assertEqual(self.irc.state.history[-1].channel, None) self.assertEqual(self.irc.state.history[-1].channel, None)
def testFilterErrors(self):
self.irc.reset()
while self.irc.takeMsg() is not None:
pass
class BuggyCallback(irclib.IrcCallback):
infilter_called = False
outfilter_called = False
def name(self):
return 'buggycallback'
def inFilter(self, irc, msg):
self.infilter_called = True
raise Exception('test exception')
def outFilter(self, irc, msg):
self.outfilter_called = True
raise Exception('test exception')
class Callback(irclib.IrcCallback):
channels_set = None
def name(self):
return 'testcallback'
def doCommand(self, irc, msg):
irc.sendMsg(ircmsgs.privmsg('#foo', 'bar'))
def inFilter(self, irc, msg):
self.infilter_called = True
raise Exception('test exception')
def outFilter(self, irc, msg):
self.outfilter_called = True
raise Exception('test exception')
bc = BuggyCallback()
self.irc.addCallback(bc)
c = Callback()
self.irc.addCallback(c)
self.irc.feedMsg(ircmsgs.IrcMsg('COMMAND blah'))
m = self.irc.takeMsg()
self.assertEqual(m, ircmsgs.privmsg('#foo', 'bar'))
self.assertTrue(bc.infilter_called)
self.assertTrue(bc.outfilter_called)
self.assertTrue(c.infilter_called)
self.assertTrue(c.outfilter_called)
def testQuit(self): def testQuit(self):
self.irc.reset() self.irc.reset()
self.irc.feedMsg(ircmsgs.IrcMsg(':someuser JOIN #foo')) self.irc.feedMsg(ircmsgs.IrcMsg(':someuser JOIN #foo'))