##// END OF EJS Templates
exceptions: fixed problem with exceptions formatting resulting in limited exception data reporting.
milka -
r4627:40c3334b stable
parent child Browse files
Show More
@@ -1,234 +1,234 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2014-2020 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 Custom vcs exceptions module.
23 23 """
24 24 import logging
25 25 import functools
26 26 import urllib2
27 27 import rhodecode
28 28 from pyramid import compat
29 29
30 30 log = logging.getLogger(__name__)
31 31
32 32
33 33 class VCSCommunicationError(Exception):
34 34 pass
35 35
36 36
37 37 class HttpVCSCommunicationError(VCSCommunicationError):
38 38 pass
39 39
40 40
41 41 class VCSError(Exception):
42 42 pass
43 43
44 44
45 45 class RepositoryError(VCSError):
46 46 pass
47 47
48 48
49 49 class RepositoryRequirementError(RepositoryError):
50 50 pass
51 51
52 52
53 53 class UnresolvedFilesInRepo(RepositoryError):
54 54 pass
55 55
56 56
57 57 class VCSBackendNotSupportedError(VCSError):
58 58 """
59 59 Exception raised when VCSServer does not support requested backend
60 60 """
61 61
62 62
63 63 class EmptyRepositoryError(RepositoryError):
64 64 pass
65 65
66 66
67 67 class TagAlreadyExistError(RepositoryError):
68 68 pass
69 69
70 70
71 71 class TagDoesNotExistError(RepositoryError):
72 72 pass
73 73
74 74
75 75 class BranchAlreadyExistError(RepositoryError):
76 76 pass
77 77
78 78
79 79 class BranchDoesNotExistError(RepositoryError):
80 80 pass
81 81
82 82
83 83 class CommitError(RepositoryError):
84 84 """
85 85 Exceptions related to an existing commit
86 86 """
87 87
88 88
89 89 class CommitDoesNotExistError(CommitError):
90 90 pass
91 91
92 92
93 93 class CommittingError(RepositoryError):
94 94 """
95 95 Exceptions happening while creating a new commit
96 96 """
97 97
98 98
99 99 class NothingChangedError(CommittingError):
100 100 pass
101 101
102 102
103 103 class NodeError(VCSError):
104 104 pass
105 105
106 106
107 107 class RemovedFileNodeError(NodeError):
108 108 pass
109 109
110 110
111 111 class NodeAlreadyExistsError(CommittingError):
112 112 pass
113 113
114 114
115 115 class NodeAlreadyChangedError(CommittingError):
116 116 pass
117 117
118 118
119 119 class NodeDoesNotExistError(CommittingError):
120 120 pass
121 121
122 122
123 123 class NodeNotChangedError(CommittingError):
124 124 pass
125 125
126 126
127 127 class NodeAlreadyAddedError(CommittingError):
128 128 pass
129 129
130 130
131 131 class NodeAlreadyRemovedError(CommittingError):
132 132 pass
133 133
134 134
135 135 class SubrepoMergeError(RepositoryError):
136 136 """
137 137 This happens if we try to merge a repository which contains subrepos and
138 138 the subrepos cannot be merged. The subrepos are not merged itself but
139 139 their references in the root repo are merged.
140 140 """
141 141
142 142
143 143 class ImproperArchiveTypeError(VCSError):
144 144 pass
145 145
146 146
147 147 class CommandError(VCSError):
148 148 pass
149 149
150 150
151 151 class UnhandledException(VCSError):
152 152 """
153 153 Signals that something unexpected went wrong.
154 154
155 155 This usually means we have a programming error on the side of the VCSServer
156 156 and should inspect the logfile of the VCSServer to find more details.
157 157 """
158 158
159 159
160 160 _EXCEPTION_MAP = {
161 161 'abort': RepositoryError,
162 162 'archive': ImproperArchiveTypeError,
163 163 'error': RepositoryError,
164 164 'lookup': CommitDoesNotExistError,
165 165 'repo_locked': RepositoryError,
166 166 'requirement': RepositoryRequirementError,
167 167 'unhandled': UnhandledException,
168 168 # TODO: johbo: Define our own exception for this and stop abusing
169 169 # urllib's exception class.
170 170 'url_error': urllib2.URLError,
171 171 'subrepo_merge_error': SubrepoMergeError,
172 172 }
173 173
174 174
175 175 def map_vcs_exceptions(func):
176 176 """
177 177 Utility to decorate functions so that plain exceptions are translated.
178 178
179 179 The translation is based on `exc_map` which maps a `str` indicating
180 180 the error type into an exception class representing this error inside
181 181 of the vcs layer.
182 182 """
183 183
184 184 @functools.wraps(func)
185 185 def wrapper(*args, **kwargs):
186 186 try:
187 187 return func(*args, **kwargs)
188 188 except Exception as e:
189 189 from rhodecode.lib.utils2 import str2bool
190 190 debug = str2bool(rhodecode.CONFIG.get('debug'))
191 191
192 192 # The error middleware adds information if it finds
193 193 # __traceback_info__ in a frame object. This way the remote
194 194 # traceback information is made available in error reports.
195 195 remote_tb = getattr(e, '_vcs_server_traceback', None)
196 196 org_remote_tb = getattr(e, '_vcs_server_org_exc_tb', '')
197 197 __traceback_info__ = None
198 198 if remote_tb:
199 199 if isinstance(remote_tb, compat.string_types):
200 200 remote_tb = [remote_tb]
201 201 __traceback_info__ = (
202 202 'Found VCSServer remote traceback information:\n'
203 203 '{}\n'
204 204 '+++ BEG SOURCE EXCEPTION +++\n\n'
205 205 '{}\n'
206 206 '+++ END SOURCE EXCEPTION +++\n'
207 207 ''.format('\n'.join(remote_tb), org_remote_tb)
208 208 )
209 209
210 210 # Avoid that remote_tb also appears in the frame
211 211 del remote_tb
212 212
213 213 # Special vcs errors had an attribute "_vcs_kind" which is used
214 214 # to translate them to the proper exception class in the vcs
215 215 # client layer.
216 216 kind = getattr(e, '_vcs_kind', None)
217 217 exc_name = getattr(e, '_vcs_server_org_exc_name', None)
218 218
219 219 if kind:
220 220 if any(e.args):
221 221 _args = [a for a in e.args]
222 222 # replace the first argument with a prefix exc name
223 args = ['{}:'.format(exc_name, _args[0] if _args else '?')] + _args[1:]
223 args = ['{}:{}'.format(exc_name, _args[0] if _args else '?')] + _args[1:]
224 224 else:
225 225 args = [__traceback_info__ or '{}: UnhandledException'.format(exc_name)]
226 226 if debug or __traceback_info__ and kind not in ['unhandled', 'lookup']:
227 227 # for other than unhandled errors also log the traceback
228 228 # can be useful for debugging
229 229 log.error(__traceback_info__)
230 230
231 231 raise _EXCEPTION_MAP[kind](*args)
232 232 else:
233 233 raise
234 234 return wrapper
General Comments 0
You need to be logged in to leave comments. Login now