##// END OF EJS Templates
error-handling: Remove if condition to check if the response is a vcs response....
Martin Bornhold -
r949:706ee3c3 default
parent child Browse files
Show More
@@ -1,106 +1,99 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2016 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21
22 22 import logging
23 23 from pyramid import httpexceptions
24 24 from pyramid.httpexceptions import HTTPError, HTTPInternalServerError
25 25 from pyramid.threadlocal import get_current_request
26 26
27 27 from rhodecode.lib.exceptions import VCSServerUnavailable
28 28 from rhodecode.lib.vcs.exceptions import VCSCommunicationError
29 29
30 30
31 31 log = logging.getLogger(__name__)
32 32
33 33
34 34 class PylonsErrorHandlingMiddleware(object):
35 35 """
36 36 This middleware is wrapped around the old pylons application to catch
37 37 errors and invoke our error handling view to return a proper error page.
38 38 """
39 39 def __init__(self, app, error_view, reraise=False):
40 40 self.app = app
41 41 self.error_view = error_view
42 42 self._reraise = reraise
43 43
44 44 def __call__(self, environ, start_response):
45 45 # We need to use the pyramid request here instead of creating a custom
46 46 # instance from the environ because this request maybe passed to the
47 47 # error handler view which is a pyramid view and expects a pyramid
48 48 # request which has been processed by the pyramid router.
49 49 request = get_current_request()
50 50
51 51 response = self.handle_request(request)
52 52 return response(environ, start_response)
53 53
54 def is_vcs_response(self, response):
55 return 'X-RhodeCode-Backend' in response.headers
56
57 54 def is_http_error(self, response):
58 55 # webob type error responses
59 56 return (400 <= response.status_int <= 599)
60 57
61 def is_error_handling_needed(self, response):
62 return (self.is_http_error(response) and not
63 self.is_vcs_response(response))
64
65 58 def reraise(self):
66 59 return self._reraise
67 60
68 61 def handle_request(self, request):
69 62 """
70 63 Calls the underlying WSGI app (typically the old RhodeCode pylons app)
71 64 and returns the response if no error happened. In case of an error it
72 65 invokes the error handling view to return a proper error page as
73 66 response.
74 67
75 68 - old webob type exceptions get converted to pyramid exceptions
76 69 - pyramid exceptions are passed to the error handler view
77 70 """
78 71 try:
79 72 response = request.get_response(self.app)
80 if self.is_error_handling_needed(response):
73 if self.is_http_error(response):
81 74 response = webob_to_pyramid_http_response(response)
82 75 return self.error_view(response, request)
83 76 except HTTPError as e: # pyramid type exceptions
84 77 return self.error_view(e, request)
85 78 except Exception as e:
86 79 log.exception(e)
87 80
88 81 if self.reraise():
89 82 raise
90 83
91 84 if isinstance(e, VCSCommunicationError):
92 85 return self.error_view(VCSServerUnavailable(), request)
93 86
94 87 return self.error_view(HTTPInternalServerError(), request)
95 88
96 89 return response
97 90
98 91
99 92 def webob_to_pyramid_http_response(webob_response):
100 93 ResponseClass = httpexceptions.status_map[webob_response.status_int]
101 94 pyramid_response = ResponseClass(webob_response.status)
102 95 pyramid_response.status = webob_response.status
103 96 pyramid_response.headers.update(webob_response.headers)
104 97 if pyramid_response.headers['content-type'] == 'text/html':
105 98 pyramid_response.headers['content-type'] = 'text/html; charset=UTF-8'
106 99 return pyramid_response
General Comments 0
You need to be logged in to leave comments. Login now