From 088d0f54dd68d12e0b74f9f7405978816021bf85 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Thu, 17 Mar 2022 22:29:10 +0100 Subject: [PATCH] irclib: Catch exception from outFilter, as with inFilter --- src/irclib.py | 6 +++++- test/test_irclib.py | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/irclib.py b/src/irclib.py index 533173841..ae15a8d47 100644 --- a/src/irclib.py +++ b/src/irclib.py @@ -1527,7 +1527,11 @@ class Irc(IrcCommandDispatcher, log.Firewalled): msg._len = msg._str = None for callback in reversed(self.callbacks): 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: log.debug('%s.outFilter returned None.', callback.name()) return self.takeMsg() diff --git a/test/test_irclib.py b/test/test_irclib.py index cb020373b..be5a360ec 100644 --- a/test/test_irclib.py +++ b/test/test_irclib.py @@ -1023,6 +1023,46 @@ class IrcTestCase(SupyTestCase): self.irc.feedMsg(ircmsgs.IrcMsg('MODE @#linux3 +v foo')) 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): self.irc.reset() self.irc.feedMsg(ircmsgs.IrcMsg(':someuser JOIN #foo'))