Skip to content
Snippets Groups Projects
Commit 051e1718 authored by Per Cederqvist's avatar Per Cederqvist
Browse files

New file.

(Remote): New class.
(Remote.__init__): New method.
(serialize): New function.
(re_raise): New function.
parent da1e5ea1
No related branches found
No related tags found
No related merge requests found
"""Exception handling for remote processes.
If you have a controller process that spawns a child process, and
an unexpected exception occurs in the child process, you often want
to report it via the controller process. Perhaps it can be handled
in the controller process. At the very least, you want to get a
traceback from the child process.
This module defines a new exception, Remote, which encapsulates any
other exception (as long as the other exception only contains data
that can be cPickled). It also provides two functions:
- serialize: call this in an exception handler in the child
process. It will create a Remote exception based on
sys.exc_info(), serialize it, and return it as a string.
- re_raise: when given a string produced by serialize(), it will
raise the Remote exception.
This module does not attempt to transfer the serialized exception
from the child process to the controller process. It is assumed
that you already have a channel where that can be done.
Typical usage:
In the client:
try:
# Code that can raise an exception
except:
x = remote_exception.serialize()
# Somehow send x to the controller.
In the server:
# Somehow receive the serialized string into x.
remote_exception.re_raise(x)
See the test code at the end of this module for working demo code.
"""
import sys
import cPickle
import traceback
class Remote(Exception):
"""An exception occured in a remote process.
This exception defines these attributes:
- exc_type -- The type of the original exception.
- exc_value -- The value of the original exception.
- traceback -- A preformatted traceback string, ready for
printing (or writing to a log file, et c).
"""
def __init__(self):
"""Create a Remote exception.
The exception data will be gathered using sys.exc_info(),
so this must be created inside an except clause.
"""
self.exc_type, self.exc_value, tb = sys.exc_info()
self.traceback = ''.join(traceback.format_exception(
self.exc_type, self.exc_value, tb))
Exception.__init__(self, self.exc_type.__name__, str(self.exc_value))
def serialize():
"""Create a Remote exception, serialize it, and return the string.
This must be called from within an except clause.
"""
x = Remote()
return cPickle.dumps(x, cPickle.HIGHEST_PROTOCOL)
def re_raise(s):
"""Decode a serialized Remote exception, and raise it."""
raise cPickle.loads(s)
# Demo code follows.
if __name__ == "__main__":
try:
x
except:
y = serialize()
try:
re_raise(y)
except Remote, z:
print "Remote exception follows:"
print z.traceback
print "The exception was re-generated here:"
print ''.join(traceback.format_exception(*sys.exc_info()))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment