Created
August 24, 2016 03:50
-
-
Save jianingy/dd45a9976d48fc8ad25753592115bc96 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def deserialize_remote_exception(conf, data): | |
failure = jsonutils.loads(str(data)) | |
trace = failure.get('tb', []) | |
message = failure.get('message', "") + "\n" + "\n".join(trace) | |
name = failure.get('class') | |
module = failure.get('module') | |
# NOTE(ameade): We DO NOT want to allow just any module to be imported, in | |
# order to prevent arbitrary code execution. | |
if module not in conf.allowed_rpc_exception_modules: | |
return RemoteError(name, failure.get('message'), trace) | |
try: | |
mod = importutils.import_module(module) | |
klass = getattr(mod, name) | |
if not issubclass(klass, Exception): | |
raise TypeError("Can only deserialize Exceptions") | |
failure = klass(*failure.get('args', []), **failure.get('kwargs', {})) | |
except (AttributeError, TypeError, ImportError): | |
return RemoteError(name, failure.get('message'), trace) | |
ex_type = type(failure) | |
str_override = lambda self: message | |
new_ex_type = type(ex_type.__name__ + _REMOTE_POSTFIX, (ex_type,), | |
{'__str__': str_override, '__unicode__': str_override}) | |
new_ex_type.__module__ = '%s%s' % (module, _REMOTE_POSTFIX) | |
try: | |
# NOTE(ameade): Dynamically create a new exception type and swap it in | |
# as the new type for the exception. This only works on user defined | |
# Exceptions and not core python exceptions. This is important because | |
# we cannot necessarily change an exception message so we must override | |
# the __str__ method. | |
failure.__class__ = new_ex_type | |
except TypeError: | |
# NOTE(ameade): If a core exception then just add the traceback to the | |
# first exception argument. | |
failure.args = (message,) + failure.args[1:] | |
return failure |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment