Make ProcessExecutionError picklable
Serialising/deserialising exceptions in python follows the protocol defined by pickle. It relies on the base Exception.__init__ setting self.args, and later resurrects exceptions with class(*args). This change rewrites processutils.ProcessExecutionError so it survives a pickle.dumps/loads round-trip. Change-Id: I9b8d104f60df868be7b808c72c932d08f1752777
This commit is contained in:
parent
fa04ee7df3
commit
9d28946395
@ -63,26 +63,33 @@ class UnknownArgumentError(Exception):
|
||||
class ProcessExecutionError(Exception):
|
||||
def __init__(self, stdout=None, stderr=None, exit_code=None, cmd=None,
|
||||
description=None):
|
||||
super(ProcessExecutionError, self).__init__(
|
||||
stdout, stderr, exit_code, cmd, description)
|
||||
self.exit_code = exit_code
|
||||
self.stderr = stderr
|
||||
self.stdout = stdout
|
||||
self.cmd = cmd
|
||||
self.description = description
|
||||
|
||||
def __str__(self):
|
||||
description = self.description
|
||||
if description is None:
|
||||
description = _("Unexpected error while running command.")
|
||||
|
||||
exit_code = self.exit_code
|
||||
if exit_code is None:
|
||||
exit_code = '-'
|
||||
|
||||
message = _('%(description)s\n'
|
||||
'Command: %(cmd)s\n'
|
||||
'Exit code: %(exit_code)s\n'
|
||||
'Stdout: %(stdout)r\n'
|
||||
'Stderr: %(stderr)r') % {'description': description,
|
||||
'cmd': cmd,
|
||||
'cmd': self.cmd,
|
||||
'exit_code': exit_code,
|
||||
'stdout': stdout,
|
||||
'stderr': stderr}
|
||||
super(ProcessExecutionError, self).__init__(message)
|
||||
'stdout': self.stdout,
|
||||
'stderr': self.stderr}
|
||||
return message
|
||||
|
||||
|
||||
class NoRootWrapSpecified(Exception):
|
||||
|
@ -19,6 +19,7 @@ import errno
|
||||
import logging
|
||||
import multiprocessing
|
||||
import os
|
||||
import pickle
|
||||
import resource
|
||||
import stat
|
||||
import subprocess
|
||||
@ -467,6 +468,21 @@ grep foo
|
||||
def test_binary_undecodable_bytes_error(self):
|
||||
self.check_undecodable_bytes_error(True)
|
||||
|
||||
def test_picklable(self):
|
||||
exc = processutils.ProcessExecutionError(
|
||||
stdout='my stdout', stderr='my stderr',
|
||||
exit_code=42, cmd='my cmd',
|
||||
description='my description')
|
||||
exc_message = str(exc)
|
||||
|
||||
exc = pickle.loads(pickle.dumps(exc))
|
||||
self.assertEqual('my stdout', exc.stdout)
|
||||
self.assertEqual('my stderr', exc.stderr)
|
||||
self.assertEqual(42, exc.exit_code)
|
||||
self.assertEqual('my cmd', exc.cmd)
|
||||
self.assertEqual('my description', exc.description)
|
||||
self.assertEqual(exc_message, str(exc))
|
||||
|
||||
|
||||
class ProcessExecutionErrorLoggingTest(test_base.BaseTestCase):
|
||||
def setUp(self):
|
||||
|
Loading…
Reference in New Issue
Block a user