changeset 5987:ada7b0495b9f

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)
author domruf <dominikruf@gmail.com>
date Tue, 14 Jun 2016 22:14:39 +0200
parents b99e00fb6dd4
children 02cfb2197c63
files kallithea/lib/middleware/simplehg.py
diffstat 1 files changed, 13 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/lib/middleware/simplehg.py	Sat Jun 25 02:57:44 2016 +0200
+++ b/kallithea/lib/middleware/simplehg.py	Tue Jun 14 22:14:39 2016 +0200
@@ -217,6 +217,7 @@
             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 @@
         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):
         """