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