[Twisted-Python] Problem with Deferreds

Chris Norman chris.norman2 at googlemail.com
Sat Apr 2 03:35:01 MDT 2016


Hi all,
I recently got over myself and forced myself to read about Deferreds 
rather than using threading opperations.

I've used them successfully in a couple of places, but this one has me 
flummoxed:

Here's the code for the Deferred and it's sub-commands:

  def do_command(self, cmd, **kwargs):
   """Process a command in true Deferred style."""
   if cmd.permissions(self.connection):
    cmd(self.connection, **kwargs)
   else:
    logger.warning('Blocked from running command %s which is secured 
with %s.', cmd.__name__, cmd.permissions.__name__)
    raise CommandError('You have insufficient privileges to perform this 
action. The staff have been notified.')

  def handle_error(self, err):
   """Handle an error from do_command."""
   if isinstance(err, CommandError):
    return self.send_error(e.message, disconnect = e.disconnect)
   else:
    self.log(e, level = 'exception')
    self.send_error('Sorry, but a problem with the server means your 
command was not executed. The staff have been notified.')

  def lineReceived(self, line):
   """Parse an incoming command."""
   global lines
   lines += 1 # Increment the line count.
   data = line.decode(settings.ENCODING)
   try:
    command, kwargs = json.loads(data)
    if not isinstance(command, string_types) or not isinstance(kwargs, 
dict):
     raise TypeError('Expecting [str, dict]. Got [%s, %s] instead.' % 
(type(command), type(kwargs)))
   except (TypeError, ValueError) as e:
    self.log('Invalid command string: %s', data, level = 'error')
    self.log(e, level = 'exception')
    return self.send_error('Invalid command.', disconnect = True)
   cmd = commands.commands.get(command, None)
   if cmd  is None:
    self.log('Unrecognised command: %s.', command, level = 'warning')
   elif self.connection.player or not cmd.login_required:
    d = defer.Deferred()
    print('Adding callback.')
    d.addCallback(self.do_command, **kwargs)
    print('Adding errback.')
    d.addErrback(self.handle_error)
    print('Calling callback.')
    d.callback(cmd)
    print('Called.') # Never gets this far.
    return d
   else:
    return self.send_error('Not authenticated.', disconnect = True)

Here's the traceback I get when the callback gets called:

Unhandled Error
Traceback (most recent call last):
   File "server/functions.py", line 88, in server_start
     reactor.run()
   File 
"/usr/local/lib/python3.5/site-packages/Twisted-16.0.0-py3.5.egg/twisted/internet/base.py", 
line 1194, in run
     self.mainLoop()
   File 
"/usr/local/lib/python3.5/site-packages/Twisted-16.0.0-py3.5.egg/twisted/internet/base.py", 
line 1206, in mainLoop
     self.doIteration(t)
   File 
"/usr/local/lib/python3.5/site-packages/Twisted-16.0.0-py3.5.egg/twisted/internet/epollreactor.py", 
line 396, in doPoll
     log.callWithLogger(selectable, _drdw, selectable, fd, event)
--- <exception caught here> ---
   File 
"/usr/local/lib/python3.5/site-packages/Twisted-16.0.0-py3.5.egg/twisted/python/log.py", 
line 101, in callWithLogger
     return callWithContext({"system": lp}, func, *args, **kw)
   File 
"/usr/local/lib/python3.5/site-packages/Twisted-16.0.0-py3.5.egg/twisted/python/log.py", 
line 84, in callWithContext
     return context.call({ILogContext: newCtx}, func, *args, **kw)
   File 
"/usr/local/lib/python3.5/site-packages/Twisted-16.0.0-py3.5.egg/twisted/python/context.py", 
line 118, in callWithContext
     return self.currentContext().callWithContext(ctx, func, *args, **kw)
   File 
"/usr/local/lib/python3.5/site-packages/Twisted-16.0.0-py3.5.egg/twisted/python/context.py", 
line 81, in callWithContext
     return func(*args,**kw)
   File 
"/usr/local/lib/python3.5/site-packages/Twisted-16.0.0-py3.5.egg/twisted/internet/posixbase.py", 
line 610, in _doReadOrWrite
     self._disconnectSelectable(selectable, why, inRead)
   File 
"/usr/local/lib/python3.5/site-packages/Twisted-16.0.0-py3.5.egg/twisted/internet/posixbase.py", 
line 258, in _disconnectSelectable
     selectable.connectionLost(failure.Failure(why))
   File 
"/usr/local/lib/python3.5/site-packages/Twisted-16.0.0-py3.5.egg/twisted/python/failure.py", 
line 232, in __init__
     tb = self.value.__traceback__
builtins.AttributeError: 'Deferred' object has no attribute '__traceback__'

Anyone have any ideas?

Cheers,

Chris



More information about the Twisted-Python mailing list