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