mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-22 09:50:37 +00:00
Fix serialization of CalledProcessError
This commit is contained in:
parent
17a4511ee1
commit
e9a3845281
2 changed files with 32 additions and 2 deletions
|
@ -3,9 +3,14 @@ import os
|
|||
|
||||
def log_check_call(command, stdin=None, env=None, shell=False, cwd=None):
|
||||
status, stdout, stderr = log_call(command, stdin, env, shell, cwd)
|
||||
from subprocess import CalledProcessError
|
||||
if status != 0:
|
||||
from subprocess import CalledProcessError
|
||||
raise CalledProcessError(status, ' '.join(command), '\n'.join(stderr))
|
||||
e = CalledProcessError(status, ' '.join(command), '\n'.join(stderr))
|
||||
# Fix Pyro4's fixIronPythonExceptionForPickle() by setting the args property,
|
||||
# even though we use our own serialization (at least I think that's the problem).
|
||||
# See bootstrapvz.remote.serialize_called_process_error for more info.
|
||||
setattr(e, 'args', (status, ' '.join(command), '\n'.join(stderr)))
|
||||
raise e
|
||||
return stdout
|
||||
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ supported_exceptions = ['bootstrapvz.common.exceptions.ManifestError',
|
|||
'bootstrapvz.base.pkg.exceptions.SourceError',
|
||||
'bootstrapvz.common.exceptions.UnitError',
|
||||
'bootstrapvz.common.fsm_proxy.FSMProxyError',
|
||||
'subprocess.CalledProcessError',
|
||||
]
|
||||
|
||||
|
||||
|
@ -41,6 +42,8 @@ def register_deserialization_handlers():
|
|||
SerializerBase.register_dict_to_class(supported_class, deserialize)
|
||||
for supported_exc in supported_exceptions:
|
||||
SerializerBase.register_dict_to_class(supported_exc, deserialize_exception)
|
||||
import subprocess
|
||||
SerializerBase.register_class_to_dict(subprocess.CalledProcessError, serialize_called_process_error)
|
||||
|
||||
|
||||
def unregister_deserialization_handlers():
|
||||
|
@ -73,6 +76,28 @@ def deserialize(fq_classname, data):
|
|||
return instance
|
||||
|
||||
|
||||
def serialize_called_process_error(obj):
|
||||
# This is by far the weirdest exception serialization.
|
||||
# There is a bug in both Pyro4 and the Python subprocess module.
|
||||
# CalledProcessError does not populate its args property,
|
||||
# although according to https://docs.python.org/2/library/exceptions.html#exceptions.BaseException.args
|
||||
# it should...
|
||||
# So we populate that property during serialization instead
|
||||
# (the code is grabbed directly from Pyro4's class_to_dict())
|
||||
# However, Pyro4 still cannot figure out to call the deserializer
|
||||
# unless we also use setattr() on the exception to set the args below
|
||||
# (before throwing it).
|
||||
# Mind you, the error "__init__() takes at least 3 arguments (2 given)"
|
||||
# is thrown *on the server* if we don't use setattr().
|
||||
# It's all very confusing to me and I'm not entirely
|
||||
# sure what the exact problem is. Regardless - it works, so there.
|
||||
return {'__class__': obj.__class__.__module__ + '.' + obj.__class__.__name__,
|
||||
'__exception__': True,
|
||||
'args': (obj.returncode, obj.cmd, obj.output),
|
||||
'attributes': vars(obj) # add custom exception attributes
|
||||
}
|
||||
|
||||
|
||||
def get_class_object(fq_classname):
|
||||
parts = fq_classname.split('.')
|
||||
module_name = '.'.join(parts[:-1])
|
||||
|
|
Loading…
Add table
Reference in a new issue