Permalink
Browse files

Traceback in client

Refactored exception communication to add traceback information as
list of strings. You can print the server traceback in the proxy side
by calling `set_excepthook()`. Additionally, if the environmental variable
`PZC_HIDE_TRACEBACK` is True (default) the traceback corresponding
to pizco will be hidden.
  • Loading branch information...
1 parent 1c7103f commit 4e7a19816cd656faf2b9def48d141d6b778c6bfb @hgrecco committed Nov 27, 2012
Showing with 23 additions and 4 deletions.
  1. +23 −4 pizco/pizco.py
View
27 pizco/pizco.py
@@ -21,6 +21,7 @@
import inspect
import logging
import threading
+import traceback
import subprocess
from collections import defaultdict
@@ -56,6 +57,8 @@ def compare_digest(a, b):
DEFAULT_LAUNCHER = os.environ.get('PZC_DEFAULT_LAUNCHER', None)
+HIDE_TRACEBACK = os.environ.get('PZC_HIDE_TRACEBACK', True)
+
if not DEFAULT_LAUNCHER:
sw = sys.platform.startswith
if sw('linux'):
@@ -734,7 +737,8 @@ def on_request(self, sender, topic, content, msgid):
elif action == 'instantiate':
if self.served_object is not None:
- return PSMessage('raise', Exception('Cannot instantiate another object.'))
+ return PSMessage('raise', (Exception('Cannot instantiate another object.'),
+ ''))
mod_name, class_name = options['class'].rsplit('.', 1)
mod = __import__(mod_name, fromlist=[class_name])
@@ -743,7 +747,7 @@ def on_request(self, sender, topic, content, msgid):
return PSMessage('return', None)
else:
ret = Exception('invalid message action {}'.format(action))
- return PSMessage('raise', ret)
+ return PSMessage('raise', (ret, ''))
if isinstance(ret, futures.Future):
ret.add_done_callback(lambda fut: self.publish('__future__',
@@ -755,7 +759,9 @@ def on_request(self, sender, topic, content, msgid):
return PSMessage('return', ret)
except Exception as ex:
- return PSMessage('raise', ex)
+ exc_type, exc_value, exc_tb = sys.exc_info()
+ tb = traceback.format_exception(exc_type, exc_value, exc_tb)[1:]
+ return PSMessage('raise', (ex, tb))
def emit(self, topic, value, old_value, other):
logger.debug('Emitting {}, {}, {}, {}'.format(topic, value, old_value, other))
@@ -893,7 +899,9 @@ def request_server(self, action, options, force_as_object=False):
raise ValueError('Invalid response from Server {}'.format(content))
if ret_action == 'raise':
- raise ret_options
+ exc, traceback_text = ret_options
+ exc._pzc_traceback = traceback_text
+ raise exc
elif ret_action == 'remote':
return RemoteAttribute(options['name'], self.request_server, self.signal_manager)
elif ret_action == 'return':
@@ -940,6 +948,17 @@ def instantiate(self, served_cls, args, kwargs):
self.request_server('instantiate', {'class': served_cls, 'args': args, 'kwargs': kwargs})
+def _except_hook(type, value, tb):
+ for item in traceback.format_exception(type, value, tb)[:-1] + getattr(value, '_pzc_traceback', []):
+ if HIDE_TRACEBACK and 'pizco.py' in item:
+ continue
+ sys.stderr.write(item)
+
+
+def set_excepthook():
+ sys.excepthook = _except_hook
+
+
class Proxy(object):
"""Proxy object to access a server.

0 comments on commit 4e7a198

Please sign in to comment.