import pwd
import sys
from multiprocessing import Process, Queue
-
+from traceback import format_exception_only, extract_tb, format_list
_RET_FORK_OK = 0
_RET_FORK_ERR = 1
"""General error class for the source service"""
pass
+class GbpChildBTError(Exception):
+ """Exception for handling unhandled child exceptions in fork_call()"""
+ def __init__(self, *args):
+ self.typ, self.val, traceback = sys.exc_info()
+ self.tb_list = extract_tb(traceback)
+ super(GbpChildBTError, self).__init__(*args)
+
+ def prettyprint_tb(self):
+ """Get traceback in a format easier to comprehend"""
+ child_tb = format_list(self.tb_list)
+ child_tb += format_exception_only(self.typ, self.val)
+ sep = '-' * 4 + ' CHILD TRACEBACK ' + '-' * 50 + '\n'
+ pp_tb = sep + ''.join(child_tb) + sep
+ return pp_tb
+
+
def _demoted_child_call(uid, gid, ret_data_q, func, args, kwargs):
"""Call a function/method with different uid/gid"""
# Set UID and GID
try:
ret = func(*args, **kwargs)
except Exception as err:
- ret_data_q.put(err)
+ ret_data_q.put(GbpChildBTError())
sys.exit(_RET_FORK_ERR)
else:
ret_data_q.put(ret)
from gbp_repocache import MirrorGitRepository
from obs_service_gbp_utils import fork_call, _demoted_child_call, _RET_FORK_OK
-from obs_service_gbp_utils import GbpServiceError, write_treeish_meta
+from obs_service_gbp_utils import write_treeish_meta
+from obs_service_gbp_utils import GbpServiceError, GbpChildBTError
from tests import UnitTestsBase
def test_fail(self):
"""Tests for function call failures"""
- with assert_raises(_DummyException):
+ with assert_raises(GbpChildBTError) as exc:
fork_call(None, None, self._dummy_raise)
+ eq_(exc.exception.typ, _DummyException)
- with assert_raises(TypeError):
+ with assert_raises(GbpChildBTError) as exc:
fork_call(None, None, self._dummy_ok, 'unexptected_arg')
+ eq_(exc.exception.typ, TypeError)
def test_demoted_call_no(self):
"""Test running with different UID/GID"""
self._no_fork_call(99999, None, self._dummy_ok)
with assert_raises(GbpServiceError):
self._no_fork_call(None, 99999, self._dummy_ok)
- with assert_raises(_DummyException):
+ with assert_raises(GbpChildBTError) as exc:
self._no_fork_call(self._uid, self._gid, self._dummy_raise)
+ eq_(exc.exception.typ, _DummyException)
class TestGitMeta(UnitTestsBase):
"""Test writing treeish meta into a file"""