From 5855f1739f17d24243c16b7fb017f4b52dca45cd Mon Sep 17 00:00:00 2001 From: David Wilson Date: Tue, 27 Feb 2018 12:21:51 +0545 Subject: [PATCH] core: Handle unpicklable data in dispatch_calls() Sending just via .call_async() would previously crash the child, now it generates CallError like intended. --- mitogen/core.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/mitogen/core.py b/mitogen/core.py index d8ffbb13..836c451a 100644 --- a/mitogen/core.py +++ b/mitogen/core.py @@ -1330,24 +1330,27 @@ class ExternalContext(object): finally: fp.close() + def _dispatch_one(self, msg): + data = msg.unpickle(throw=False) + _v and LOG.debug('_dispatch_calls(%r)', data) + if msg.auth_id not in mitogen.parent_ids: + LOG.warning('CALL_FUNCTION from non-parent %r', msg.auth_id) + + modname, klass, func, args, kwargs = data + obj = __import__(modname, {}, {}, ['']) + if klass: + obj = getattr(obj, klass) + fn = getattr(obj, func) + if getattr(fn, 'mitogen_takes_econtext', None): + kwargs.setdefault('econtext', self) + if getattr(fn, 'mitogen_takes_router', None): + kwargs.setdefault('router', self.router) + return fn(*args, **kwargs) + def _dispatch_calls(self): for msg in self.channel: - data = msg.unpickle(throw=False) - _v and LOG.debug('_dispatch_calls(%r)', data) - if msg.auth_id not in mitogen.parent_ids: - LOG.warning('CALL_FUNCTION from non-parent %r', msg.auth_id) - - modname, klass, func, args, kwargs = data try: - obj = __import__(modname, {}, {}, ['']) - if klass: - obj = getattr(obj, klass) - fn = getattr(obj, func) - if getattr(fn, 'mitogen_takes_econtext', None): - kwargs.setdefault('econtext', self) - if getattr(fn, 'mitogen_takes_router', None): - kwargs.setdefault('router', self.router) - msg.reply(fn(*args, **kwargs)) + msg.reply(self._dispatch_one(msg)) except Exception, e: _v and LOG.debug('_dispatch_calls: %s', e) msg.reply(CallError(e))