Show More
@@ -18,6 +18,7 b'' | |||
|
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 | import sys | |
|
21 | 22 | import logging |
|
22 | 23 | |
|
23 | 24 | |
@@ -73,16 +74,35 b' class Pyro4AwareFormatter(logging.Format' | |||
|
73 | 74 | |
|
74 | 75 | def formatException(self, ei): |
|
75 | 76 | ex_type, ex_value, ex_tb = ei |
|
76 | if hasattr(ex_value, '_pyroTraceback'): | |
|
77 | # johbo: Avoiding to import pyro4 until we get an exception | |
|
78 | # which actually has a remote traceback. This avoids issues | |
|
79 | # when gunicorn is used with gevent, since the logging would | |
|
80 | # trigger an import of Pyro4 before the patches of gevent | |
|
81 | # are applied. | |
|
82 | import Pyro4.util | |
|
83 | return ''.join( | |
|
84 | Pyro4.util.getPyroTraceback(ex_type, ex_value, ex_tb)) | |
|
85 | return logging.Formatter.formatException(self, ei) | |
|
77 | ||
|
78 | local_tb = logging.Formatter.formatException(self, ei) | |
|
79 | if hasattr(ex_value, '_vcs_server_traceback'): | |
|
80 | ||
|
81 | def formatRemoteTraceback(remote_tb_lines): | |
|
82 | result = ["\n +--- This exception occured remotely on VCSServer - Remote traceback:\n\n"] | |
|
83 | result.append(remote_tb_lines) | |
|
84 | result.append("\n +--- End of remote traceback\n") | |
|
85 | return result | |
|
86 | ||
|
87 | try: | |
|
88 | if ex_type is not None and ex_value is None and ex_tb is None: | |
|
89 | # possible old (3.x) call syntax where caller is only providing exception object | |
|
90 | if type(ex_type) is not type: | |
|
91 | raise TypeError( | |
|
92 | "invalid argument: ex_type should be an exception type, or just supply no arguments at all") | |
|
93 | if ex_type is None and ex_tb is None: | |
|
94 | ex_type, ex_value, ex_tb = sys.exc_info() | |
|
95 | ||
|
96 | remote_tb = getattr(ex_value, "_vcs_server_traceback", None) | |
|
97 | ||
|
98 | if remote_tb: | |
|
99 | remote_tb = formatRemoteTraceback(remote_tb) | |
|
100 | return local_tb + ''.join(remote_tb) | |
|
101 | finally: | |
|
102 | # clean up cycle to traceback, to allow proper GC | |
|
103 | del ex_type, ex_value, ex_tb | |
|
104 | ||
|
105 | return local_tb | |
|
86 | 106 | |
|
87 | 107 | |
|
88 | 108 | class ColorFormatter(Pyro4AwareFormatter): |
@@ -75,7 +75,7 b' def wrap_in_appenlight_if_enabled(app, s' | |||
|
75 | 75 | |
|
76 | 76 | class RemoteTracebackTracker(object): |
|
77 | 77 | """ |
|
78 |
Utility middleware which forwards |
|
|
78 | Utility middleware which forwards VCSServer remote traceback information. | |
|
79 | 79 | """ |
|
80 | 80 | |
|
81 | 81 | def __init__(self, app): |
@@ -85,7 +85,7 b' class RemoteTracebackTracker(object):' | |||
|
85 | 85 | try: |
|
86 | 86 | return self.application(environ, start_response) |
|
87 | 87 | except Exception as e: |
|
88 |
if hasattr(e, '_ |
|
|
88 | if hasattr(e, '_vcs_server_traceback'): | |
|
89 | 89 | track_extra_information( |
|
90 |
environ, 'remote_traceback', |
|
|
90 | environ, 'remote_traceback', e._vcs_server_traceback) | |
|
91 | 91 | raise |
@@ -218,6 +218,12 b' def _remote_call(url, payload, exception' | |||
|
218 | 218 | exc._vcs_kind = error['_vcs_kind'] |
|
219 | 219 | except KeyError: |
|
220 | 220 | pass |
|
221 | ||
|
222 | try: | |
|
223 | exc._vcs_server_traceback = error['traceback'] | |
|
224 | except KeyError: | |
|
225 | pass | |
|
226 | ||
|
221 | 227 | raise exc |
|
222 | 228 | return response.get('result') |
|
223 | 229 |
@@ -185,10 +185,10 b' def map_vcs_exceptions(func):' | |||
|
185 | 185 | # The error middleware adds information if it finds |
|
186 | 186 | # __traceback_info__ in a frame object. This way the remote |
|
187 | 187 | # traceback information is made available in error reports. |
|
188 |
remote_tb = getattr(e, '_ |
|
|
188 | remote_tb = getattr(e, '_vcs_server_traceback', None) | |
|
189 | 189 | if remote_tb: |
|
190 | 190 | __traceback_info__ = ( |
|
191 |
'Found |
|
|
191 | 'Found VCSServer remote traceback information:\n\n' + | |
|
192 | 192 | '\n'.join(remote_tb)) |
|
193 | 193 | |
|
194 | 194 | # Avoid that remote_tb also appears in the frame |
@@ -46,6 +46,7 b' function registerRCRoutes() {' | |||
|
46 | 46 | pyroutes.register('files_home', '/%(repo_name)s/files/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']); |
|
47 | 47 | pyroutes.register('files_history_home', '/%(repo_name)s/history/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']); |
|
48 | 48 | pyroutes.register('files_authors_home', '/%(repo_name)s/authors/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']); |
|
49 | pyroutes.register('files_annotate_home', '/%(repo_name)s/annotate/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']); | |
|
49 | 50 | pyroutes.register('files_archive_home', '/%(repo_name)s/archive/%(fname)s', ['repo_name', 'fname']); |
|
50 | 51 | pyroutes.register('files_nodelist_home', '/%(repo_name)s/nodelist/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']); |
|
51 | 52 | pyroutes.register('files_nodetree_full', '/%(repo_name)s/nodetree_full/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']); |
@@ -1331,22 +1331,21 b' def pytest_runtest_makereport(item, call' | |||
|
1331 | 1331 | """ |
|
1332 | 1332 | Adding the remote traceback if the exception has this information. |
|
1333 | 1333 | |
|
1334 |
Pyro4 attaches this information as the attribute `_ |
|
|
1334 | Pyro4 attaches this information as the attribute `_vcs_server_traceback` | |
|
1335 | 1335 | to the exception instance. |
|
1336 | 1336 | """ |
|
1337 | 1337 | outcome = yield |
|
1338 | 1338 | report = outcome.get_result() |
|
1339 | 1339 | if call.excinfo: |
|
1340 |
_add_ |
|
|
1340 | _add_vcsserver_remote_traceback(report, call.excinfo.value) | |
|
1341 | 1341 | |
|
1342 | 1342 | |
|
1343 |
def _add_ |
|
|
1344 |
|
|
|
1343 | def _add_vcsserver_remote_traceback(report, exc): | |
|
1344 | vcsserver_traceback = getattr(exc, '_vcs_server_traceback', None) | |
|
1345 | 1345 | |
|
1346 |
if |
|
|
1347 | traceback = ''.join(pyro_traceback) | |
|
1348 | section = 'Pyro4 remote traceback ' + report.when | |
|
1349 | report.sections.append((section, traceback)) | |
|
1346 | if vcsserver_traceback: | |
|
1347 | section = 'VCSServer remote traceback ' + report.when | |
|
1348 | report.sections.append((section, vcsserver_traceback)) | |
|
1350 | 1349 | |
|
1351 | 1350 | |
|
1352 | 1351 | @pytest.fixture(scope='session') |
General Comments 0
You need to be logged in to leave comments.
Login now