##// END OF EJS Templates
error: add a structured exception for unsupported merge records...
Siddharth Agarwal -
r26985:039a53c8 default
parent child Browse files
Show More
@@ -1,222 +1,232 b''
1 # error.py - Mercurial exceptions
1 # error.py - Mercurial exceptions
2 #
2 #
3 # Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 """Mercurial exceptions.
8 """Mercurial exceptions.
9
9
10 This allows us to catch exceptions at higher levels without forcing
10 This allows us to catch exceptions at higher levels without forcing
11 imports.
11 imports.
12 """
12 """
13
13
14 from __future__ import absolute_import
14 from __future__ import absolute_import
15
15
16 # Do not import anything here, please
16 # Do not import anything here, please
17
17
18 class HintException(Exception):
18 class HintException(Exception):
19 def __init__(self, *args, **kw):
19 def __init__(self, *args, **kw):
20 Exception.__init__(self, *args)
20 Exception.__init__(self, *args)
21 self.hint = kw.get('hint')
21 self.hint = kw.get('hint')
22
22
23 class RevlogError(HintException):
23 class RevlogError(HintException):
24 pass
24 pass
25
25
26 class FilteredIndexError(IndexError):
26 class FilteredIndexError(IndexError):
27 pass
27 pass
28
28
29 class LookupError(RevlogError, KeyError):
29 class LookupError(RevlogError, KeyError):
30 def __init__(self, name, index, message):
30 def __init__(self, name, index, message):
31 self.name = name
31 self.name = name
32 self.index = index
32 self.index = index
33 # this can't be called 'message' because at least some installs of
33 # this can't be called 'message' because at least some installs of
34 # Python 2.6+ complain about the 'message' property being deprecated
34 # Python 2.6+ complain about the 'message' property being deprecated
35 self.lookupmessage = message
35 self.lookupmessage = message
36 if isinstance(name, str) and len(name) == 20:
36 if isinstance(name, str) and len(name) == 20:
37 from .node import short
37 from .node import short
38 name = short(name)
38 name = short(name)
39 RevlogError.__init__(self, '%s@%s: %s' % (index, name, message))
39 RevlogError.__init__(self, '%s@%s: %s' % (index, name, message))
40
40
41 def __str__(self):
41 def __str__(self):
42 return RevlogError.__str__(self)
42 return RevlogError.__str__(self)
43
43
44 class FilteredLookupError(LookupError):
44 class FilteredLookupError(LookupError):
45 pass
45 pass
46
46
47 class ManifestLookupError(LookupError):
47 class ManifestLookupError(LookupError):
48 pass
48 pass
49
49
50 class CommandError(Exception):
50 class CommandError(Exception):
51 """Exception raised on errors in parsing the command line."""
51 """Exception raised on errors in parsing the command line."""
52
52
53 class InterventionRequired(Exception):
53 class InterventionRequired(Exception):
54 """Exception raised when a command requires human intervention."""
54 """Exception raised when a command requires human intervention."""
55
55
56 class Abort(HintException):
56 class Abort(HintException):
57 """Raised if a command needs to print an error and exit."""
57 """Raised if a command needs to print an error and exit."""
58
58
59 class HookLoadError(Abort):
59 class HookLoadError(Abort):
60 """raised when loading a hook fails, aborting an operation
60 """raised when loading a hook fails, aborting an operation
61
61
62 Exists to allow more specialized catching."""
62 Exists to allow more specialized catching."""
63
63
64 class HookAbort(Abort):
64 class HookAbort(Abort):
65 """raised when a validation hook fails, aborting an operation
65 """raised when a validation hook fails, aborting an operation
66
66
67 Exists to allow more specialized catching."""
67 Exists to allow more specialized catching."""
68
68
69 class ConfigError(Abort):
69 class ConfigError(Abort):
70 """Exception raised when parsing config files"""
70 """Exception raised when parsing config files"""
71
71
72 class UpdateAbort(Abort):
72 class UpdateAbort(Abort):
73 """Raised when an update is aborted for destination issue"""
73 """Raised when an update is aborted for destination issue"""
74
74
75 class ResponseExpected(Abort):
75 class ResponseExpected(Abort):
76 """Raised when an EOF is received for a prompt"""
76 """Raised when an EOF is received for a prompt"""
77 def __init__(self):
77 def __init__(self):
78 from .i18n import _
78 from .i18n import _
79 Abort.__init__(self, _('response expected'))
79 Abort.__init__(self, _('response expected'))
80
80
81 class OutOfBandError(Exception):
81 class OutOfBandError(Exception):
82 """Exception raised when a remote repo reports failure"""
82 """Exception raised when a remote repo reports failure"""
83
83
84 def __init__(self, *args, **kw):
84 def __init__(self, *args, **kw):
85 Exception.__init__(self, *args)
85 Exception.__init__(self, *args)
86 self.hint = kw.get('hint')
86 self.hint = kw.get('hint')
87
87
88 class ParseError(Exception):
88 class ParseError(Exception):
89 """Raised when parsing config files and {rev,file}sets (msg[, pos])"""
89 """Raised when parsing config files and {rev,file}sets (msg[, pos])"""
90
90
91 class UnknownIdentifier(ParseError):
91 class UnknownIdentifier(ParseError):
92 """Exception raised when a {rev,file}set references an unknown identifier"""
92 """Exception raised when a {rev,file}set references an unknown identifier"""
93
93
94 def __init__(self, function, symbols):
94 def __init__(self, function, symbols):
95 from .i18n import _
95 from .i18n import _
96 ParseError.__init__(self, _("unknown identifier: %s") % function)
96 ParseError.__init__(self, _("unknown identifier: %s") % function)
97 self.function = function
97 self.function = function
98 self.symbols = symbols
98 self.symbols = symbols
99
99
100 class RepoError(HintException):
100 class RepoError(HintException):
101 pass
101 pass
102
102
103 class RepoLookupError(RepoError):
103 class RepoLookupError(RepoError):
104 pass
104 pass
105
105
106 class FilteredRepoLookupError(RepoLookupError):
106 class FilteredRepoLookupError(RepoLookupError):
107 pass
107 pass
108
108
109 class CapabilityError(RepoError):
109 class CapabilityError(RepoError):
110 pass
110 pass
111
111
112 class RequirementError(RepoError):
112 class RequirementError(RepoError):
113 """Exception raised if .hg/requires has an unknown entry."""
113 """Exception raised if .hg/requires has an unknown entry."""
114
114
115 class UnsupportedMergeRecords(Abort):
116 def __init__(self, recordtypes):
117 from .i18n import _
118 self.recordtypes = sorted(recordtypes)
119 s = ' '.join(self.recordtypes)
120 Abort.__init__(
121 self, _('unsupported merge state records: %s') % s,
122 hint=_('see https://mercurial-scm.org/wiki/MergeStateRecords for '
123 'more information'))
124
115 class LockError(IOError):
125 class LockError(IOError):
116 def __init__(self, errno, strerror, filename, desc):
126 def __init__(self, errno, strerror, filename, desc):
117 IOError.__init__(self, errno, strerror, filename)
127 IOError.__init__(self, errno, strerror, filename)
118 self.desc = desc
128 self.desc = desc
119
129
120 class LockHeld(LockError):
130 class LockHeld(LockError):
121 def __init__(self, errno, filename, desc, locker):
131 def __init__(self, errno, filename, desc, locker):
122 LockError.__init__(self, errno, 'Lock held', filename, desc)
132 LockError.__init__(self, errno, 'Lock held', filename, desc)
123 self.locker = locker
133 self.locker = locker
124
134
125 class LockUnavailable(LockError):
135 class LockUnavailable(LockError):
126 pass
136 pass
127
137
128 # LockError is for errors while acquiring the lock -- this is unrelated
138 # LockError is for errors while acquiring the lock -- this is unrelated
129 class LockInheritanceContractViolation(RuntimeError):
139 class LockInheritanceContractViolation(RuntimeError):
130 pass
140 pass
131
141
132 class ResponseError(Exception):
142 class ResponseError(Exception):
133 """Raised to print an error with part of output and exit."""
143 """Raised to print an error with part of output and exit."""
134
144
135 class UnknownCommand(Exception):
145 class UnknownCommand(Exception):
136 """Exception raised if command is not in the command table."""
146 """Exception raised if command is not in the command table."""
137
147
138 class AmbiguousCommand(Exception):
148 class AmbiguousCommand(Exception):
139 """Exception raised if command shortcut matches more than one command."""
149 """Exception raised if command shortcut matches more than one command."""
140
150
141 # derived from KeyboardInterrupt to simplify some breakout code
151 # derived from KeyboardInterrupt to simplify some breakout code
142 class SignalInterrupt(KeyboardInterrupt):
152 class SignalInterrupt(KeyboardInterrupt):
143 """Exception raised on SIGTERM and SIGHUP."""
153 """Exception raised on SIGTERM and SIGHUP."""
144
154
145 class SignatureError(Exception):
155 class SignatureError(Exception):
146 pass
156 pass
147
157
148 class PushRaced(RuntimeError):
158 class PushRaced(RuntimeError):
149 """An exception raised during unbundling that indicate a push race"""
159 """An exception raised during unbundling that indicate a push race"""
150
160
151 # bundle2 related errors
161 # bundle2 related errors
152 class BundleValueError(ValueError):
162 class BundleValueError(ValueError):
153 """error raised when bundle2 cannot be processed"""
163 """error raised when bundle2 cannot be processed"""
154
164
155 class BundleUnknownFeatureError(BundleValueError):
165 class BundleUnknownFeatureError(BundleValueError):
156 def __init__(self, parttype=None, params=(), values=()):
166 def __init__(self, parttype=None, params=(), values=()):
157 self.parttype = parttype
167 self.parttype = parttype
158 self.params = params
168 self.params = params
159 self.values = values
169 self.values = values
160 if self.parttype is None:
170 if self.parttype is None:
161 msg = 'Stream Parameter'
171 msg = 'Stream Parameter'
162 else:
172 else:
163 msg = parttype
173 msg = parttype
164 entries = self.params
174 entries = self.params
165 if self.params and self.values:
175 if self.params and self.values:
166 assert len(self.params) == len(self.values)
176 assert len(self.params) == len(self.values)
167 entries = []
177 entries = []
168 for idx, par in enumerate(self.params):
178 for idx, par in enumerate(self.params):
169 val = self.values[idx]
179 val = self.values[idx]
170 if val is None:
180 if val is None:
171 entries.append(val)
181 entries.append(val)
172 else:
182 else:
173 entries.append("%s=%r" % (par, val))
183 entries.append("%s=%r" % (par, val))
174 if entries:
184 if entries:
175 msg = '%s - %s' % (msg, ', '.join(entries))
185 msg = '%s - %s' % (msg, ', '.join(entries))
176 ValueError.__init__(self, msg)
186 ValueError.__init__(self, msg)
177
187
178 class ReadOnlyPartError(RuntimeError):
188 class ReadOnlyPartError(RuntimeError):
179 """error raised when code tries to alter a part being generated"""
189 """error raised when code tries to alter a part being generated"""
180
190
181 class PushkeyFailed(Abort):
191 class PushkeyFailed(Abort):
182 """error raised when a pushkey part failed to update a value"""
192 """error raised when a pushkey part failed to update a value"""
183
193
184 def __init__(self, partid, namespace=None, key=None, new=None, old=None,
194 def __init__(self, partid, namespace=None, key=None, new=None, old=None,
185 ret=None):
195 ret=None):
186 self.partid = partid
196 self.partid = partid
187 self.namespace = namespace
197 self.namespace = namespace
188 self.key = key
198 self.key = key
189 self.new = new
199 self.new = new
190 self.old = old
200 self.old = old
191 self.ret = ret
201 self.ret = ret
192 # no i18n expected to be processed into a better message
202 # no i18n expected to be processed into a better message
193 Abort.__init__(self, 'failed to update value for "%s/%s"'
203 Abort.__init__(self, 'failed to update value for "%s/%s"'
194 % (namespace, key))
204 % (namespace, key))
195
205
196 class CensoredNodeError(RevlogError):
206 class CensoredNodeError(RevlogError):
197 """error raised when content verification fails on a censored node
207 """error raised when content verification fails on a censored node
198
208
199 Also contains the tombstone data substituted for the uncensored data.
209 Also contains the tombstone data substituted for the uncensored data.
200 """
210 """
201
211
202 def __init__(self, filename, node, tombstone):
212 def __init__(self, filename, node, tombstone):
203 from .node import short
213 from .node import short
204 RevlogError.__init__(self, '%s:%s' % (filename, short(node)))
214 RevlogError.__init__(self, '%s:%s' % (filename, short(node)))
205 self.tombstone = tombstone
215 self.tombstone = tombstone
206
216
207 class CensoredBaseError(RevlogError):
217 class CensoredBaseError(RevlogError):
208 """error raised when a delta is rejected because its base is censored
218 """error raised when a delta is rejected because its base is censored
209
219
210 A delta based on a censored revision must be formed as single patch
220 A delta based on a censored revision must be formed as single patch
211 operation which replaces the entire base with new content. This ensures
221 operation which replaces the entire base with new content. This ensures
212 the delta may be applied by clones which have not censored the base.
222 the delta may be applied by clones which have not censored the base.
213 """
223 """
214
224
215 class InvalidBundleSpecification(Exception):
225 class InvalidBundleSpecification(Exception):
216 """error raised when a bundle specification is invalid.
226 """error raised when a bundle specification is invalid.
217
227
218 This is used for syntax errors as opposed to support errors.
228 This is used for syntax errors as opposed to support errors.
219 """
229 """
220
230
221 class UnsupportedBundleSpecification(Exception):
231 class UnsupportedBundleSpecification(Exception):
222 """error raised when a bundle specification is not supported."""
232 """error raised when a bundle specification is not supported."""
General Comments 0
You need to be logged in to leave comments. Login now