# HG changeset patch # User domruf # Date 2016-06-14 22:14:39 # Node ID ada7b0495b9f61771d8baed3308de908a39f0fd8 # Parent b99e00fb6dd47d740f177799e880111af96d5a26 lock: fix for Mercurial 3.6+ - wrap hgweb to catch Locked exceptions from hooks With Mercurial 3.6, the handling of WSGI responses changed. The hook exceptions are no longer raised directly when app(environ, start_response) is called so the 'except HTTPLockedRC as e' block in _handle_request (a few lines above ) does not work anymore because the exception happens later. Therefore I created a wrapper class that can catch the exceptions. This makes locking work again and fixes lock related tests like TestVCSOperations.test_clone_after_repo_was_locked_hg which expect certain output of the hg client in case of an HTTPLockedRC exception. Depending on how https://bz.mercurial-scm.org/show_bug.cgi?id=5232 gets handled, this fix might become obsolete in the future. (Modified by Mads Kiilerich) diff --git a/kallithea/lib/middleware/simplehg.py b/kallithea/lib/middleware/simplehg.py --- a/kallithea/lib/middleware/simplehg.py +++ b/kallithea/lib/middleware/simplehg.py @@ -217,6 +217,7 @@ class SimpleHg(BaseVCSController): if str(e).find('not found') != -1: return HTTPNotFound()(environ, start_response) except HTTPLockedRC as e: + # Before Mercurial 3.6, lock exceptions were caught here log.debug('Locked, response %s: %s', e.code, e.title) return e(environ, start_response) except Exception: @@ -228,7 +229,18 @@ class SimpleHg(BaseVCSController): Make an wsgi application using hgweb, and inject generated baseui instance, additionally inject some extras into ui object """ - return hgweb_mod.hgweb(repo_name, name=repo_name, baseui=baseui) + class HgWebWrapper(hgweb_mod.hgweb): + # Work-around for Mercurial 3.6+ causing lock exceptions to be + # thrown late + def _runwsgi(self, req, repo): + try: + return super(HgWebWrapper, self)._runwsgi(req, repo) + except HTTPLockedRC as e: + log.debug('Locked, response %s: %s', e.code, e.title) + req.respond(e.status, 'text/plain') + return '' + + return HgWebWrapper(repo_name, name=repo_name, baseui=baseui) def __get_repository(self, environ): """