mirror of https://github.com/Mikaela/Limnoria.git
Added log.firewall and log.MetaFirewall, and converted several classes to use them.
This commit is contained in:
parent
4fec15f40e
commit
47d81547aa
|
@ -83,11 +83,7 @@ class AsyncoreDriver(asynchat.async_chat, object):
|
|||
|
||||
def writable(self):
|
||||
while self.connected:
|
||||
try:
|
||||
m = self.irc.takeMsg()
|
||||
except Exception, e:
|
||||
log.exception('Uncaught exception in irclib.Irc.takeMsg:')
|
||||
return
|
||||
m = self.irc.takeMsg()
|
||||
if m:
|
||||
self.push(str(m))
|
||||
else:
|
||||
|
|
|
@ -434,13 +434,7 @@ class IrcObjectProxy(RichReplyMethods):
|
|||
log.debug('Finished calling invalidCommand: %s', cb.name())
|
||||
return
|
||||
if hasattr(cb, 'invalidCommand'):
|
||||
try:
|
||||
cb.invalidCommand(self, self.msg, self.args)
|
||||
except Exception, e:
|
||||
cb.log.exception('Uncaught exception in invalidCommand:')
|
||||
log.warning('Uncaught exception in %s.invalidCommand, '
|
||||
'continuing to call other invalidCommands.' %
|
||||
cb.name())
|
||||
cb.invalidCommand(self, self.msg, self.args)
|
||||
|
||||
def _callCommand(self, name, command, cb):
|
||||
try:
|
||||
|
@ -669,6 +663,8 @@ class ConfigIrcProxy(RichReplyMethods):
|
|||
|
||||
class Privmsg(irclib.IrcCallback):
|
||||
"""Base class for all Privmsg handlers."""
|
||||
__metaclass__ = log.MetaFirewall
|
||||
__firewalled__ = {'invalidCommand': None} # Eventually callCommand.
|
||||
threaded = False
|
||||
public = True
|
||||
alwaysCall = ()
|
||||
|
|
|
@ -75,6 +75,13 @@ class IrcCallback(IrcCommandDispatcher):
|
|||
# priority means the callback is called *earlier* on the inFilter chain,
|
||||
# *earlier* on the __call__ chain, and *later* on the outFilter chain.
|
||||
priority = 99
|
||||
__metaclass__ = log.MetaFirewall
|
||||
__firewalled__ = {'die': None,
|
||||
'reset': None,
|
||||
'__call__': None,
|
||||
'inFilter': lambda self, irc, msg: msg,
|
||||
'outFilter': lambda self, irc, msg: msg,
|
||||
'name': lambda self: self.__class__.__name__,}
|
||||
def name(self):
|
||||
"""Returns the name of the callback."""
|
||||
return self.__class__.__name__
|
||||
|
@ -99,11 +106,7 @@ class IrcCallback(IrcCommandDispatcher):
|
|||
"""Used for handling each message."""
|
||||
method = self.dispatchCommand(msg.command)
|
||||
if method is not None:
|
||||
try:
|
||||
method(irc, msg)
|
||||
except Exception, e:
|
||||
s = 'Exception caught in generic IrcCallback.__call__:'
|
||||
log.exception(s)
|
||||
method(irc, msg)
|
||||
|
||||
def reset(self):
|
||||
"""Resets the callback. Called when reconnecting to the server."""
|
||||
|
@ -263,6 +266,8 @@ class IrcState(IrcCommandDispatcher):
|
|||
"""Maintains state of the Irc connection. Should also become smarter.
|
||||
"""
|
||||
__slots__ = ('history', 'nicksToHostmasks', 'channels')
|
||||
__metaclass__ = log.MetaFirewall
|
||||
__firewalled__ = {'addMsg': None}
|
||||
def __init__(self):
|
||||
self.history = RingBuffer(conf.supybot.maxHistoryLength())
|
||||
self.reset()
|
||||
|
@ -411,6 +416,10 @@ class Irc(IrcCommandDispatcher):
|
|||
|
||||
Handles PING commands already.
|
||||
"""
|
||||
__metaclass__ = log.MetaFirewall
|
||||
__firewalled__ = {'die': None,
|
||||
'feedMsg': None,
|
||||
'takeMsg': None,}
|
||||
_nickSetters = sets.Set(['001', '002', '003', '004', '250', '251', '252',
|
||||
'254', '255', '265', '266', '372', '375', '376',
|
||||
'333', '353', '332', '366', '005'])
|
||||
|
@ -520,31 +529,16 @@ class Irc(IrcCommandDispatcher):
|
|||
if msg:
|
||||
log.debug(repr(msg))
|
||||
for callback in reviter(self.callbacks):
|
||||
try:
|
||||
outFilter = getattr(callback, 'outFilter')
|
||||
except AttributeError, e:
|
||||
continue
|
||||
try:
|
||||
msg = outFilter(self, msg)
|
||||
except:
|
||||
log.exception('Exception caught in outFilter:')
|
||||
continue
|
||||
msg = callback.outFilter(self, msg)
|
||||
if msg is None:
|
||||
log.debug('%s.outFilter returned None' % callback.name())
|
||||
log.debug('%s.outFilter returned None.' % callback.name())
|
||||
return self.takeMsg()
|
||||
if len(str(msg)) > 512:
|
||||
# Yes, this violates the contract, but at this point it doesn't
|
||||
# matter. That's why we gotta go munging in private attributes
|
||||
msg._str = msg._str[:500] + '\r\n'
|
||||
msg._len = len(str(msg))
|
||||
try:
|
||||
self.state.addMsg(self, msg)
|
||||
except Exception, e:
|
||||
log.exception('Uncaught exception in IrcState.addMsg. This '
|
||||
'could be a bug, but it could also be the '
|
||||
'result of an invalid message being sent via '
|
||||
'Owner.ircquote.')
|
||||
return
|
||||
self.state.addMsg(self, msg)
|
||||
log.debug('Outgoing message: ' + str(msg).rstrip('\r\n'))
|
||||
return msg
|
||||
else:
|
||||
|
@ -668,10 +662,7 @@ class Irc(IrcCommandDispatcher):
|
|||
log.info('Irc object for %s dying.' % self.server)
|
||||
if self in world.ircs:
|
||||
for cb in self.callbacks:
|
||||
try:
|
||||
cb.die()
|
||||
except Exception, e:
|
||||
log.exception('Uncaught exception in %s.die:', cb.name())
|
||||
cb.die()
|
||||
world.ircs.remove(self)
|
||||
else:
|
||||
log.warning('Irc object killed twice.')
|
||||
|
|
40
src/log.py
40
src/log.py
|
@ -42,6 +42,7 @@ import logging
|
|||
|
||||
import ansi
|
||||
import conf
|
||||
import utils
|
||||
import registry
|
||||
|
||||
deadlyExceptions = [KeyboardInterrupt, SystemExit]
|
||||
|
@ -166,6 +167,45 @@ def timestamp(when=None):
|
|||
format = conf.supybot.log.timestampFormat()
|
||||
return time.strftime(format, time.localtime(when))
|
||||
|
||||
def firewall(f, errorHandler=None):
|
||||
def logException(self, s=None):
|
||||
if s is None:
|
||||
s = 'Uncaught exception'
|
||||
if hasattr(self, 'log'):
|
||||
self.log.exception('%s:', s)
|
||||
else:
|
||||
exception('%s in %s.%s:', s, self.__class__.__name__, f.func_name)
|
||||
def m(self, *args, **kwargs):
|
||||
try:
|
||||
return f(self, *args, **kwargs)
|
||||
except Exception, e:
|
||||
logException(self)
|
||||
if errorHandler is not None:
|
||||
try:
|
||||
errorHandler(self, *args, **kwargs)
|
||||
except Exception, e:
|
||||
logException(self, 'Uncaught exception in errorHandler')
|
||||
|
||||
m = utils.changeFunctionName(m, f.func_name, f.__doc__)
|
||||
return m
|
||||
|
||||
class MetaFirewall(type):
|
||||
def __new__(cls, name, bases, dict):
|
||||
firewalled = {}
|
||||
for base in bases:
|
||||
if hasattr(base, '__firewalled__'):
|
||||
firewalled.update(base.__firewalled__)
|
||||
if '__firewalled__' in dict:
|
||||
firewalled.update(dict['__firewalled__'])
|
||||
for attr in firewalled:
|
||||
if attr in dict:
|
||||
try:
|
||||
errorHandler = firewalled[attr]
|
||||
except:
|
||||
errorHandler = None
|
||||
dict[attr] = firewall(dict[attr], errorHandler)
|
||||
return type.__new__(cls, name, bases, dict)
|
||||
|
||||
|
||||
class LogLevel(registry.Value):
|
||||
def set(self, s):
|
||||
|
|
|
@ -75,11 +75,7 @@ class SocketDriver(drivers.IrcDriver):
|
|||
self.reconnect()
|
||||
|
||||
def _sendIfMsgs(self):
|
||||
try:
|
||||
msgs = [self.irc.takeMsg()]
|
||||
except Exception, e:
|
||||
log.exception('Uncaught exception in irclib.Irc.takeMsg:')
|
||||
return
|
||||
msgs = [self.irc.takeMsg()]
|
||||
while msgs[-1] is not None:
|
||||
msgs.append(self.irc.takeMsg())
|
||||
del msgs[-1]
|
||||
|
|
|
@ -69,11 +69,7 @@ class SupyIrcProtocol(LineReceiver):
|
|||
|
||||
def checkIrcForMsgs(self):
|
||||
if self.connected:
|
||||
try:
|
||||
msg = self.irc.takeMsg()
|
||||
except Exception, e:
|
||||
log.exception('Uncaught exception in irclib.Irc.takeMsg:')
|
||||
return
|
||||
msg = self.irc.takeMsg()
|
||||
if msg:
|
||||
self.transport.write(str(msg))
|
||||
self.mostRecentCall = reactor.callLater(1, self.checkIrcForMsgs)
|
||||
|
|
Loading…
Reference in New Issue