# HG changeset patch # User Marcin Kuzminski # Date 2017-02-23 11:51:45 # Node ID c608ea737ba78409291cdcccd705b7dfadee1b98 # Parent 88d2ba782aa39f28d7f84bc65f43af4979824dc3 exception-handling: better handling of remote exception and logging. - detect traceback sent form the remote sides - unified handling of exception handling in backends diff --git a/vcsserver/base.py b/vcsserver/base.py --- a/vcsserver/base.py +++ b/vcsserver/base.py @@ -15,6 +15,8 @@ # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +import sys +import traceback import logging import urlparse @@ -80,3 +82,17 @@ def obfuscate_qs(query_string): return '&'.join('{}{}'.format( k, '={}'.format(v) if v else '') for k, v in parsed) + + +def raise_from_original(new_type): + """ + Raise a new exception type with original args and traceback. + """ + exc_type, exc_value, exc_traceback = sys.exc_info() + + traceback.format_exception(exc_type, exc_value, exc_traceback) + + try: + raise new_type(*exc_value.args), None, exc_traceback + finally: + del exc_traceback diff --git a/vcsserver/git.py b/vcsserver/git.py --- a/vcsserver/git.py +++ b/vcsserver/git.py @@ -35,7 +35,7 @@ from dulwich.server import update_server from vcsserver import exceptions, settings, subprocessio from vcsserver.utils import safe_str -from vcsserver.base import RepoFactory, obfuscate_qs +from vcsserver.base import RepoFactory, obfuscate_qs, raise_from_original from vcsserver.hgcompat import ( hg_url as url_parser, httpbasicauthhandler, httpdigestauthhandler) @@ -58,6 +58,11 @@ def reraise_safe_exceptions(func): raise exceptions.LookupException(e.message) except (HangupException, UnexpectedCommandError) as e: raise exceptions.VcsException(e.message) + except Exception as e: + if not hasattr(e, '_vcs_kind'): + log.exception("Unhandled exception in git remote call") + raise_from_original(exceptions.UnhandledException) + raise return wrapper diff --git a/vcsserver/hg.py b/vcsserver/hg.py --- a/vcsserver/hg.py +++ b/vcsserver/hg.py @@ -18,7 +18,6 @@ import io import logging import stat -import sys import urllib import urllib2 @@ -28,7 +27,7 @@ from mercurial import commands from mercurial import unionrepo from vcsserver import exceptions -from vcsserver.base import RepoFactory, obfuscate_qs +from vcsserver.base import RepoFactory, obfuscate_qs, raise_from_original from vcsserver.hgcompat import ( archival, bin, clone, config as hgconfig, diffopts, hex, hg_url as url_parser, httpbasicauthhandler, httpdigestauthhandler, @@ -91,17 +90,6 @@ def reraise_safe_exceptions(func): return wrapper -def raise_from_original(new_type): - """ - Raise a new exception type with original args and traceback. - """ - _, original, traceback = sys.exc_info() - try: - raise new_type(*original.args), None, traceback - finally: - del traceback - - class MercurialFactory(RepoFactory): def _create_config(self, config, hooks=True): diff --git a/vcsserver/hooks.py b/vcsserver/hooks.py --- a/vcsserver/hooks.py +++ b/vcsserver/hooks.py @@ -17,12 +17,14 @@ # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +import io +import sys +import json +import logging import collections import importlib -import io -import json import subprocess -import sys + from httplib import HTTPConnection @@ -33,6 +35,8 @@ import simplejson as json from vcsserver import exceptions +log = logging.getLogger(__name__) + class HooksHttpClient(object): connection = None @@ -105,6 +109,11 @@ class GitMessageWriter(RemoteMessageWrit def _handle_exception(result): exception_class = result.get('exception') + exception_traceback = result.get('exception_traceback') + + if exception_traceback: + log.error('Got traceback from remote call:%s', exception_traceback) + if exception_class == 'HTTPLockedRC': raise exceptions.RepositoryLockedException(*result['exception_args']) elif exception_class == 'RepositoryError': diff --git a/vcsserver/svn.py b/vcsserver/svn.py --- a/vcsserver/svn.py +++ b/vcsserver/svn.py @@ -33,7 +33,7 @@ import svn.repos from vcsserver import svn_diff from vcsserver import exceptions -from vcsserver.base import RepoFactory +from vcsserver.base import RepoFactory, raise_from_original log = logging.getLogger(__name__) @@ -62,17 +62,6 @@ def reraise_safe_exceptions(func): return wrapper -def raise_from_original(new_type): - """ - Raise a new exception type with original args and traceback. - """ - _, original, traceback = sys.exc_info() - try: - raise new_type(*original.args), None, traceback - finally: - del traceback - - class SubversionFactory(RepoFactory): def _create_repo(self, wire, create, compatible_version):