##// 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 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2014-2017 RhodeCode GmbH
3 # Copyright (C) 2014-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 Custom vcs exceptions module.
22 Custom vcs exceptions module.
23 """
23 """
24
24
25 import functools
25 import functools
26 import urllib2
26 import urllib2
27
27
28
28
29 class VCSCommunicationError(Exception):
29 class VCSCommunicationError(Exception):
30 pass
30 pass
31
31
32
32
33 class HttpVCSCommunicationError(VCSCommunicationError):
33 class HttpVCSCommunicationError(VCSCommunicationError):
34 pass
34 pass
35
35
36
36
37 class VCSError(Exception):
37 class VCSError(Exception):
38 pass
38 pass
39
39
40
40
41 class RepositoryError(VCSError):
41 class RepositoryError(VCSError):
42 pass
42 pass
43
43
44
44
45 class RepositoryRequirementError(RepositoryError):
45 class RepositoryRequirementError(RepositoryError):
46 pass
46 pass
47
47
48
48
49 class VCSBackendNotSupportedError(VCSError):
49 class VCSBackendNotSupportedError(VCSError):
50 """
50 """
51 Exception raised when VCSServer does not support requested backend
51 Exception raised when VCSServer does not support requested backend
52 """
52 """
53
53
54
54
55 class EmptyRepositoryError(RepositoryError):
55 class EmptyRepositoryError(RepositoryError):
56 pass
56 pass
57
57
58
58
59 class TagAlreadyExistError(RepositoryError):
59 class TagAlreadyExistError(RepositoryError):
60 pass
60 pass
61
61
62
62
63 class TagDoesNotExistError(RepositoryError):
63 class TagDoesNotExistError(RepositoryError):
64 pass
64 pass
65
65
66
66
67 class BranchAlreadyExistError(RepositoryError):
67 class BranchAlreadyExistError(RepositoryError):
68 pass
68 pass
69
69
70
70
71 class BranchDoesNotExistError(RepositoryError):
71 class BranchDoesNotExistError(RepositoryError):
72 pass
72 pass
73
73
74
74
75 class CommitError(RepositoryError):
75 class CommitError(RepositoryError):
76 """
76 """
77 Exceptions related to an existing commit
77 Exceptions related to an existing commit
78 """
78 """
79
79
80
80
81 class CommitDoesNotExistError(CommitError):
81 class CommitDoesNotExistError(CommitError):
82 pass
82 pass
83
83
84
84
85 class CommittingError(RepositoryError):
85 class CommittingError(RepositoryError):
86 """
86 """
87 Exceptions happening while creating a new commit
87 Exceptions happening while creating a new commit
88 """
88 """
89
89
90
90
91 class NothingChangedError(CommittingError):
91 class NothingChangedError(CommittingError):
92 pass
92 pass
93
93
94
94
95 class NodeError(VCSError):
95 class NodeError(VCSError):
96 pass
96 pass
97
97
98
98
99 class RemovedFileNodeError(NodeError):
99 class RemovedFileNodeError(NodeError):
100 pass
100 pass
101
101
102
102
103 class NodeAlreadyExistsError(CommittingError):
103 class NodeAlreadyExistsError(CommittingError):
104 pass
104 pass
105
105
106
106
107 class NodeAlreadyChangedError(CommittingError):
107 class NodeAlreadyChangedError(CommittingError):
108 pass
108 pass
109
109
110
110
111 class NodeDoesNotExistError(CommittingError):
111 class NodeDoesNotExistError(CommittingError):
112 pass
112 pass
113
113
114
114
115 class NodeNotChangedError(CommittingError):
115 class NodeNotChangedError(CommittingError):
116 pass
116 pass
117
117
118
118
119 class NodeAlreadyAddedError(CommittingError):
119 class NodeAlreadyAddedError(CommittingError):
120 pass
120 pass
121
121
122
122
123 class NodeAlreadyRemovedError(CommittingError):
123 class NodeAlreadyRemovedError(CommittingError):
124 pass
124 pass
125
125
126
126
127 class SubrepoMergeError(RepositoryError):
127 class SubrepoMergeError(RepositoryError):
128 """
128 """
129 This happens if we try to merge a repository which contains subrepos and
129 This happens if we try to merge a repository which contains subrepos and
130 the subrepos cannot be merged. The subrepos are not merged itself but
130 the subrepos cannot be merged. The subrepos are not merged itself but
131 their references in the root repo are merged.
131 their references in the root repo are merged.
132 """
132 """
133
133
134
134
135 class ImproperArchiveTypeError(VCSError):
135 class ImproperArchiveTypeError(VCSError):
136 pass
136 pass
137
137
138
138
139 class CommandError(VCSError):
139 class CommandError(VCSError):
140 pass
140 pass
141
141
142
142
143 class UnhandledException(VCSError):
143 class UnhandledException(VCSError):
144 """
144 """
145 Signals that something unexpected went wrong.
145 Signals that something unexpected went wrong.
146
146
147 This usually means we have a programming error on the side of the VCSServer
147 This usually means we have a programming error on the side of the VCSServer
148 and should inspect the logfile of the VCSServer to find more details.
148 and should inspect the logfile of the VCSServer to find more details.
149 """
149 """
150
150
151
151
152 _EXCEPTION_MAP = {
152 _EXCEPTION_MAP = {
153 'abort': RepositoryError,
153 'abort': RepositoryError,
154 'archive': ImproperArchiveTypeError,
154 'archive': ImproperArchiveTypeError,
155 'error': RepositoryError,
155 'error': RepositoryError,
156 'lookup': CommitDoesNotExistError,
156 'lookup': CommitDoesNotExistError,
157 'repo_locked': RepositoryError,
157 'repo_locked': RepositoryError,
158 'requirement': RepositoryRequirementError,
158 'requirement': RepositoryRequirementError,
159 'unhandled': UnhandledException,
159 'unhandled': UnhandledException,
160 # TODO: johbo: Define our own exception for this and stop abusing
160 # TODO: johbo: Define our own exception for this and stop abusing
161 # urllib's exception class.
161 # urllib's exception class.
162 'url_error': urllib2.URLError,
162 'url_error': urllib2.URLError,
163 'subrepo_merge_error': SubrepoMergeError,
163 'subrepo_merge_error': SubrepoMergeError,
164 }
164 }
165
165
166
166
167 def map_vcs_exceptions(func):
167 def map_vcs_exceptions(func):
168 """
168 """
169 Utility to decorate functions so that plain exceptions are translated.
169 Utility to decorate functions so that plain exceptions are translated.
170
170
171 The translation is based on `exc_map` which maps a `str` indicating
171 The translation is based on `exc_map` which maps a `str` indicating
172 the error type into an exception class representing this error inside
172 the error type into an exception class representing this error inside
173 of the vcs layer.
173 of the vcs layer.
174 """
174 """
175
175
176 @functools.wraps(func)
176 @functools.wraps(func)
177 def wrapper(*args, **kwargs):
177 def wrapper(*args, **kwargs):
178 try:
178 try:
179 return func(*args, **kwargs)
179 return func(*args, **kwargs)
180 except Exception as e:
180 except Exception as e:
181 # The error middleware adds information if it finds
181 # The error middleware adds information if it finds
182 # __traceback_info__ in a frame object. This way the remote
182 # __traceback_info__ in a frame object. This way the remote
183 # traceback information is made available in error reports.
183 # traceback information is made available in error reports.
184 remote_tb = getattr(e, '_vcs_server_traceback', None)
184 remote_tb = getattr(e, '_vcs_server_traceback', None)
185 __traceback_info__ = None
185 if remote_tb:
186 if remote_tb:
187 if isinstance(remote_tb, basestring):
188 remote_tb = [remote_tb]
186 __traceback_info__ = (
189 __traceback_info__ = (
187 'Found VCSServer remote traceback information:\n\n' +
190 'Found VCSServer remote traceback information:\n\n' +
188 '\n'.join(remote_tb))
191 '\n'.join(remote_tb))
189
192
190 # Avoid that remote_tb also appears in the frame
193 # Avoid that remote_tb also appears in the frame
191 del remote_tb
194 del remote_tb
192
195
193 # Special vcs errors had an attribute "_vcs_kind" which is used
196 # Special vcs errors had an attribute "_vcs_kind" which is used
194 # to translate them to the proper exception class in the vcs
197 # to translate them to the proper exception class in the vcs
195 # client layer.
198 # client layer.
196 kind = getattr(e, '_vcs_kind', None)
199 kind = getattr(e, '_vcs_kind', None)
200
197 if kind:
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 else:
208 else:
200 raise
209 raise
201 return wrapper
210 return wrapper
General Comments 0
You need to be logged in to leave comments. Login now