mercurial/error.py
changeset 43076 2372284d9457
parent 43034 294afb982a88
child 43077 687b865b95ad
equal deleted inserted replaced
43075:57875cf423c9 43076:2372284d9457
    13 
    13 
    14 from __future__ import absolute_import
    14 from __future__ import absolute_import
    15 
    15 
    16 # Do not import anything but pycompat here, please
    16 # Do not import anything but pycompat here, please
    17 from . import pycompat
    17 from . import pycompat
       
    18 
    18 
    19 
    19 def _tobytes(exc):
    20 def _tobytes(exc):
    20     """Byte-stringify exception in the same way as BaseException_str()"""
    21     """Byte-stringify exception in the same way as BaseException_str()"""
    21     if not exc.args:
    22     if not exc.args:
    22         return b''
    23         return b''
    23     if len(exc.args) == 1:
    24     if len(exc.args) == 1:
    24         return pycompat.bytestr(exc.args[0])
    25         return pycompat.bytestr(exc.args[0])
    25     return b'(%s)' % b', '.join(b"'%s'" % pycompat.bytestr(a) for a in exc.args)
    26     return b'(%s)' % b', '.join(b"'%s'" % pycompat.bytestr(a) for a in exc.args)
    26 
    27 
       
    28 
    27 class Hint(object):
    29 class Hint(object):
    28     """Mix-in to provide a hint of an error
    30     """Mix-in to provide a hint of an error
    29 
    31 
    30     This should come first in the inheritance list to consume a hint and
    32     This should come first in the inheritance list to consume a hint and
    31     pass remaining arguments to the exception class.
    33     pass remaining arguments to the exception class.
    32     """
    34     """
       
    35 
    33     def __init__(self, *args, **kw):
    36     def __init__(self, *args, **kw):
    34         self.hint = kw.pop(r'hint', None)
    37         self.hint = kw.pop(r'hint', None)
    35         super(Hint, self).__init__(*args, **kw)
    38         super(Hint, self).__init__(*args, **kw)
    36 
    39 
       
    40 
    37 class StorageError(Hint, Exception):
    41 class StorageError(Hint, Exception):
    38     """Raised when an error occurs in a storage layer.
    42     """Raised when an error occurs in a storage layer.
    39 
    43 
    40     Usually subclassed by a storage-specific exception.
    44     Usually subclassed by a storage-specific exception.
    41     """
    45     """
    42     __bytes__ = _tobytes
    46 
       
    47     __bytes__ = _tobytes
       
    48 
    43 
    49 
    44 class RevlogError(StorageError):
    50 class RevlogError(StorageError):
    45     __bytes__ = _tobytes
    51     __bytes__ = _tobytes
    46 
    52 
       
    53 
    47 class SidedataHashError(RevlogError):
    54 class SidedataHashError(RevlogError):
    48 
       
    49     def __init__(self, key, expected, got):
    55     def __init__(self, key, expected, got):
    50         self.sidedatakey = key
    56         self.sidedatakey = key
    51         self.expecteddigest = expected
    57         self.expecteddigest = expected
    52         self.actualdigest = got
    58         self.actualdigest = got
    53 
    59 
       
    60 
    54 class FilteredIndexError(IndexError):
    61 class FilteredIndexError(IndexError):
    55     __bytes__ = _tobytes
    62     __bytes__ = _tobytes
       
    63 
    56 
    64 
    57 class LookupError(RevlogError, KeyError):
    65 class LookupError(RevlogError, KeyError):
    58     def __init__(self, name, index, message):
    66     def __init__(self, name, index, message):
    59         self.name = name
    67         self.name = name
    60         self.index = index
    68         self.index = index
    61         # this can't be called 'message' because at least some installs of
    69         # this can't be called 'message' because at least some installs of
    62         # Python 2.6+ complain about the 'message' property being deprecated
    70         # Python 2.6+ complain about the 'message' property being deprecated
    63         self.lookupmessage = message
    71         self.lookupmessage = message
    64         if isinstance(name, bytes) and len(name) == 20:
    72         if isinstance(name, bytes) and len(name) == 20:
    65             from .node import short
    73             from .node import short
       
    74 
    66             name = short(name)
    75             name = short(name)
    67         RevlogError.__init__(self, '%s@%s: %s' % (index, name, message))
    76         RevlogError.__init__(self, '%s@%s: %s' % (index, name, message))
    68 
    77 
    69     def __bytes__(self):
    78     def __bytes__(self):
    70         return RevlogError.__bytes__(self)
    79         return RevlogError.__bytes__(self)
    71 
    80 
    72     def __str__(self):
    81     def __str__(self):
    73         return RevlogError.__str__(self)
    82         return RevlogError.__str__(self)
    74 
    83 
       
    84 
    75 class AmbiguousPrefixLookupError(LookupError):
    85 class AmbiguousPrefixLookupError(LookupError):
    76     pass
    86     pass
    77 
    87 
       
    88 
    78 class FilteredLookupError(LookupError):
    89 class FilteredLookupError(LookupError):
    79     pass
    90     pass
    80 
    91 
       
    92 
    81 class ManifestLookupError(LookupError):
    93 class ManifestLookupError(LookupError):
    82     pass
    94     pass
       
    95 
    83 
    96 
    84 class CommandError(Exception):
    97 class CommandError(Exception):
    85     """Exception raised on errors in parsing the command line."""
    98     """Exception raised on errors in parsing the command line."""
    86     __bytes__ = _tobytes
    99 
       
   100     __bytes__ = _tobytes
       
   101 
    87 
   102 
    88 class InterventionRequired(Hint, Exception):
   103 class InterventionRequired(Hint, Exception):
    89     """Exception raised when a command requires human intervention."""
   104     """Exception raised when a command requires human intervention."""
    90     __bytes__ = _tobytes
   105 
       
   106     __bytes__ = _tobytes
       
   107 
    91 
   108 
    92 class Abort(Hint, Exception):
   109 class Abort(Hint, Exception):
    93     """Raised if a command needs to print an error and exit."""
   110     """Raised if a command needs to print an error and exit."""
    94     __bytes__ = _tobytes
   111 
       
   112     __bytes__ = _tobytes
       
   113 
    95 
   114 
    96 class HookLoadError(Abort):
   115 class HookLoadError(Abort):
    97     """raised when loading a hook fails, aborting an operation
   116     """raised when loading a hook fails, aborting an operation
    98 
   117 
    99     Exists to allow more specialized catching."""
   118     Exists to allow more specialized catching."""
   100 
   119 
       
   120 
   101 class HookAbort(Abort):
   121 class HookAbort(Abort):
   102     """raised when a validation hook fails, aborting an operation
   122     """raised when a validation hook fails, aborting an operation
   103 
   123 
   104     Exists to allow more specialized catching."""
   124     Exists to allow more specialized catching."""
   105 
   125 
       
   126 
   106 class ConfigError(Abort):
   127 class ConfigError(Abort):
   107     """Exception raised when parsing config files"""
   128     """Exception raised when parsing config files"""
   108 
   129 
       
   130 
   109 class UpdateAbort(Abort):
   131 class UpdateAbort(Abort):
   110     """Raised when an update is aborted for destination issue"""
   132     """Raised when an update is aborted for destination issue"""
   111 
   133 
       
   134 
   112 class MergeDestAbort(Abort):
   135 class MergeDestAbort(Abort):
   113     """Raised when an update is aborted for destination issues"""
   136     """Raised when an update is aborted for destination issues"""
   114 
   137 
       
   138 
   115 class NoMergeDestAbort(MergeDestAbort):
   139 class NoMergeDestAbort(MergeDestAbort):
   116     """Raised when an update is aborted because there is nothing to merge"""
   140     """Raised when an update is aborted because there is nothing to merge"""
   117 
   141 
       
   142 
   118 class ManyMergeDestAbort(MergeDestAbort):
   143 class ManyMergeDestAbort(MergeDestAbort):
   119     """Raised when an update is aborted because destination is ambiguous"""
   144     """Raised when an update is aborted because destination is ambiguous"""
   120 
   145 
       
   146 
   121 class ResponseExpected(Abort):
   147 class ResponseExpected(Abort):
   122     """Raised when an EOF is received for a prompt"""
   148     """Raised when an EOF is received for a prompt"""
       
   149 
   123     def __init__(self):
   150     def __init__(self):
   124         from .i18n import _
   151         from .i18n import _
       
   152 
   125         Abort.__init__(self, _('response expected'))
   153         Abort.__init__(self, _('response expected'))
       
   154 
   126 
   155 
   127 class OutOfBandError(Hint, Exception):
   156 class OutOfBandError(Hint, Exception):
   128     """Exception raised when a remote repo reports failure"""
   157     """Exception raised when a remote repo reports failure"""
   129     __bytes__ = _tobytes
   158 
       
   159     __bytes__ = _tobytes
       
   160 
   130 
   161 
   131 class ParseError(Hint, Exception):
   162 class ParseError(Hint, Exception):
   132     """Raised when parsing config files and {rev,file}sets (msg[, pos])"""
   163     """Raised when parsing config files and {rev,file}sets (msg[, pos])"""
   133     __bytes__ = _tobytes
   164 
       
   165     __bytes__ = _tobytes
       
   166 
   134 
   167 
   135 class PatchError(Exception):
   168 class PatchError(Exception):
   136     __bytes__ = _tobytes
   169     __bytes__ = _tobytes
       
   170 
   137 
   171 
   138 class UnknownIdentifier(ParseError):
   172 class UnknownIdentifier(ParseError):
   139     """Exception raised when a {rev,file}set references an unknown identifier"""
   173     """Exception raised when a {rev,file}set references an unknown identifier"""
   140 
   174 
   141     def __init__(self, function, symbols):
   175     def __init__(self, function, symbols):
   142         from .i18n import _
   176         from .i18n import _
       
   177 
   143         ParseError.__init__(self, _("unknown identifier: %s") % function)
   178         ParseError.__init__(self, _("unknown identifier: %s") % function)
   144         self.function = function
   179         self.function = function
   145         self.symbols = symbols
   180         self.symbols = symbols
   146 
   181 
       
   182 
   147 class RepoError(Hint, Exception):
   183 class RepoError(Hint, Exception):
   148     __bytes__ = _tobytes
   184     __bytes__ = _tobytes
   149 
   185 
       
   186 
   150 class RepoLookupError(RepoError):
   187 class RepoLookupError(RepoError):
   151     pass
   188     pass
   152 
   189 
       
   190 
   153 class FilteredRepoLookupError(RepoLookupError):
   191 class FilteredRepoLookupError(RepoLookupError):
   154     pass
   192     pass
   155 
   193 
       
   194 
   156 class CapabilityError(RepoError):
   195 class CapabilityError(RepoError):
   157     pass
   196     pass
       
   197 
   158 
   198 
   159 class RequirementError(RepoError):
   199 class RequirementError(RepoError):
   160     """Exception raised if .hg/requires has an unknown entry."""
   200     """Exception raised if .hg/requires has an unknown entry."""
   161 
   201 
       
   202 
   162 class StdioError(IOError):
   203 class StdioError(IOError):
   163     """Raised if I/O to stdout or stderr fails"""
   204     """Raised if I/O to stdout or stderr fails"""
   164 
   205 
   165     def __init__(self, err):
   206     def __init__(self, err):
   166         IOError.__init__(self, err.errno, err.strerror)
   207         IOError.__init__(self, err.errno, err.strerror)
   167 
   208 
   168     # no __bytes__() because error message is derived from the standard IOError
   209     # no __bytes__() because error message is derived from the standard IOError
       
   210 
   169 
   211 
   170 class UnsupportedMergeRecords(Abort):
   212 class UnsupportedMergeRecords(Abort):
   171     def __init__(self, recordtypes):
   213     def __init__(self, recordtypes):
   172         from .i18n import _
   214         from .i18n import _
       
   215 
   173         self.recordtypes = sorted(recordtypes)
   216         self.recordtypes = sorted(recordtypes)
   174         s = ' '.join(self.recordtypes)
   217         s = ' '.join(self.recordtypes)
   175         Abort.__init__(
   218         Abort.__init__(
   176             self, _('unsupported merge state records: %s') % s,
   219             self,
   177             hint=_('see https://mercurial-scm.org/wiki/MergeStateRecords for '
   220             _('unsupported merge state records: %s') % s,
   178                    'more information'))
   221             hint=_(
       
   222                 'see https://mercurial-scm.org/wiki/MergeStateRecords for '
       
   223                 'more information'
       
   224             ),
       
   225         )
       
   226 
   179 
   227 
   180 class UnknownVersion(Abort):
   228 class UnknownVersion(Abort):
   181     """generic exception for aborting from an encounter with an unknown version
   229     """generic exception for aborting from an encounter with an unknown version
   182     """
   230     """
   183 
   231 
   184     def __init__(self, msg, hint=None, version=None):
   232     def __init__(self, msg, hint=None, version=None):
   185         self.version = version
   233         self.version = version
   186         super(UnknownVersion, self).__init__(msg, hint=hint)
   234         super(UnknownVersion, self).__init__(msg, hint=hint)
       
   235 
   187 
   236 
   188 class LockError(IOError):
   237 class LockError(IOError):
   189     def __init__(self, errno, strerror, filename, desc):
   238     def __init__(self, errno, strerror, filename, desc):
   190         IOError.__init__(self, errno, strerror, filename)
   239         IOError.__init__(self, errno, strerror, filename)
   191         self.desc = desc
   240         self.desc = desc
   192 
   241 
   193     # no __bytes__() because error message is derived from the standard IOError
   242     # no __bytes__() because error message is derived from the standard IOError
   194 
   243 
       
   244 
   195 class LockHeld(LockError):
   245 class LockHeld(LockError):
   196     def __init__(self, errno, filename, desc, locker):
   246     def __init__(self, errno, filename, desc, locker):
   197         LockError.__init__(self, errno, 'Lock held', filename, desc)
   247         LockError.__init__(self, errno, 'Lock held', filename, desc)
   198         self.locker = locker
   248         self.locker = locker
   199 
   249 
       
   250 
   200 class LockUnavailable(LockError):
   251 class LockUnavailable(LockError):
   201     pass
   252     pass
       
   253 
   202 
   254 
   203 # LockError is for errors while acquiring the lock -- this is unrelated
   255 # LockError is for errors while acquiring the lock -- this is unrelated
   204 class LockInheritanceContractViolation(RuntimeError):
   256 class LockInheritanceContractViolation(RuntimeError):
   205     __bytes__ = _tobytes
   257     __bytes__ = _tobytes
   206 
   258 
       
   259 
   207 class ResponseError(Exception):
   260 class ResponseError(Exception):
   208     """Raised to print an error with part of output and exit."""
   261     """Raised to print an error with part of output and exit."""
   209     __bytes__ = _tobytes
   262 
       
   263     __bytes__ = _tobytes
       
   264 
   210 
   265 
   211 class UnknownCommand(Exception):
   266 class UnknownCommand(Exception):
   212     """Exception raised if command is not in the command table."""
   267     """Exception raised if command is not in the command table."""
   213     __bytes__ = _tobytes
   268 
       
   269     __bytes__ = _tobytes
       
   270 
   214 
   271 
   215 class AmbiguousCommand(Exception):
   272 class AmbiguousCommand(Exception):
   216     """Exception raised if command shortcut matches more than one command."""
   273     """Exception raised if command shortcut matches more than one command."""
   217     __bytes__ = _tobytes
   274 
       
   275     __bytes__ = _tobytes
       
   276 
   218 
   277 
   219 # derived from KeyboardInterrupt to simplify some breakout code
   278 # derived from KeyboardInterrupt to simplify some breakout code
   220 class SignalInterrupt(KeyboardInterrupt):
   279 class SignalInterrupt(KeyboardInterrupt):
   221     """Exception raised on SIGTERM and SIGHUP."""
   280     """Exception raised on SIGTERM and SIGHUP."""
   222 
   281 
       
   282 
   223 class SignatureError(Exception):
   283 class SignatureError(Exception):
   224     __bytes__ = _tobytes
   284     __bytes__ = _tobytes
       
   285 
   225 
   286 
   226 class PushRaced(RuntimeError):
   287 class PushRaced(RuntimeError):
   227     """An exception raised during unbundling that indicate a push race"""
   288     """An exception raised during unbundling that indicate a push race"""
   228     __bytes__ = _tobytes
   289 
       
   290     __bytes__ = _tobytes
       
   291 
   229 
   292 
   230 class ProgrammingError(Hint, RuntimeError):
   293 class ProgrammingError(Hint, RuntimeError):
   231     """Raised if a mercurial (core or extension) developer made a mistake"""
   294     """Raised if a mercurial (core or extension) developer made a mistake"""
   232 
   295 
   233     def __init__(self, msg, *args, **kwargs):
   296     def __init__(self, msg, *args, **kwargs):
   237         msg = pycompat.sysstr(msg)
   300         msg = pycompat.sysstr(msg)
   238         super(ProgrammingError, self).__init__(msg, *args, **kwargs)
   301         super(ProgrammingError, self).__init__(msg, *args, **kwargs)
   239 
   302 
   240     __bytes__ = _tobytes
   303     __bytes__ = _tobytes
   241 
   304 
       
   305 
   242 class WdirUnsupported(Exception):
   306 class WdirUnsupported(Exception):
   243     """An exception which is raised when 'wdir()' is not supported"""
   307     """An exception which is raised when 'wdir()' is not supported"""
   244     __bytes__ = _tobytes
   308 
       
   309     __bytes__ = _tobytes
       
   310 
   245 
   311 
   246 # bundle2 related errors
   312 # bundle2 related errors
   247 class BundleValueError(ValueError):
   313 class BundleValueError(ValueError):
   248     """error raised when bundle2 cannot be processed"""
   314     """error raised when bundle2 cannot be processed"""
   249     __bytes__ = _tobytes
   315 
       
   316     __bytes__ = _tobytes
       
   317 
   250 
   318 
   251 class BundleUnknownFeatureError(BundleValueError):
   319 class BundleUnknownFeatureError(BundleValueError):
   252     def __init__(self, parttype=None, params=(), values=()):
   320     def __init__(self, parttype=None, params=(), values=()):
   253         self.parttype = parttype
   321         self.parttype = parttype
   254         self.params = params
   322         self.params = params
   269                     entries.append("%s=%r" % (par, pycompat.maybebytestr(val)))
   337                     entries.append("%s=%r" % (par, pycompat.maybebytestr(val)))
   270         if entries:
   338         if entries:
   271             msg = '%s - %s' % (msg, ', '.join(entries))
   339             msg = '%s - %s' % (msg, ', '.join(entries))
   272         ValueError.__init__(self, msg)
   340         ValueError.__init__(self, msg)
   273 
   341 
       
   342 
   274 class ReadOnlyPartError(RuntimeError):
   343 class ReadOnlyPartError(RuntimeError):
   275     """error raised when code tries to alter a part being generated"""
   344     """error raised when code tries to alter a part being generated"""
   276     __bytes__ = _tobytes
   345 
       
   346     __bytes__ = _tobytes
       
   347 
   277 
   348 
   278 class PushkeyFailed(Abort):
   349 class PushkeyFailed(Abort):
   279     """error raised when a pushkey part failed to update a value"""
   350     """error raised when a pushkey part failed to update a value"""
   280 
   351 
   281     def __init__(self, partid, namespace=None, key=None, new=None, old=None,
   352     def __init__(
   282                  ret=None):
   353         self, partid, namespace=None, key=None, new=None, old=None, ret=None
       
   354     ):
   283         self.partid = partid
   355         self.partid = partid
   284         self.namespace = namespace
   356         self.namespace = namespace
   285         self.key = key
   357         self.key = key
   286         self.new = new
   358         self.new = new
   287         self.old = old
   359         self.old = old
   288         self.ret = ret
   360         self.ret = ret
   289         # no i18n expected to be processed into a better message
   361         # no i18n expected to be processed into a better message
   290         Abort.__init__(self, 'failed to update value for "%s/%s"'
   362         Abort.__init__(
   291                        % (namespace, key))
   363             self, 'failed to update value for "%s/%s"' % (namespace, key)
       
   364         )
       
   365 
   292 
   366 
   293 class CensoredNodeError(StorageError):
   367 class CensoredNodeError(StorageError):
   294     """error raised when content verification fails on a censored node
   368     """error raised when content verification fails on a censored node
   295 
   369 
   296     Also contains the tombstone data substituted for the uncensored data.
   370     Also contains the tombstone data substituted for the uncensored data.
   297     """
   371     """
   298 
   372 
   299     def __init__(self, filename, node, tombstone):
   373     def __init__(self, filename, node, tombstone):
   300         from .node import short
   374         from .node import short
       
   375 
   301         StorageError.__init__(self, '%s:%s' % (filename, short(node)))
   376         StorageError.__init__(self, '%s:%s' % (filename, short(node)))
   302         self.tombstone = tombstone
   377         self.tombstone = tombstone
       
   378 
   303 
   379 
   304 class CensoredBaseError(StorageError):
   380 class CensoredBaseError(StorageError):
   305     """error raised when a delta is rejected because its base is censored
   381     """error raised when a delta is rejected because its base is censored
   306 
   382 
   307     A delta based on a censored revision must be formed as single patch
   383     A delta based on a censored revision must be formed as single patch
   308     operation which replaces the entire base with new content. This ensures
   384     operation which replaces the entire base with new content. This ensures
   309     the delta may be applied by clones which have not censored the base.
   385     the delta may be applied by clones which have not censored the base.
   310     """
   386     """
   311 
   387 
       
   388 
   312 class InvalidBundleSpecification(Exception):
   389 class InvalidBundleSpecification(Exception):
   313     """error raised when a bundle specification is invalid.
   390     """error raised when a bundle specification is invalid.
   314 
   391 
   315     This is used for syntax errors as opposed to support errors.
   392     This is used for syntax errors as opposed to support errors.
   316     """
   393     """
   317     __bytes__ = _tobytes
   394 
       
   395     __bytes__ = _tobytes
       
   396 
   318 
   397 
   319 class UnsupportedBundleSpecification(Exception):
   398 class UnsupportedBundleSpecification(Exception):
   320     """error raised when a bundle specification is not supported."""
   399     """error raised when a bundle specification is not supported."""
   321     __bytes__ = _tobytes
   400 
       
   401     __bytes__ = _tobytes
       
   402 
   322 
   403 
   323 class CorruptedState(Exception):
   404 class CorruptedState(Exception):
   324     """error raised when a command is not able to read its state from file"""
   405     """error raised when a command is not able to read its state from file"""
   325     __bytes__ = _tobytes
   406 
       
   407     __bytes__ = _tobytes
       
   408 
   326 
   409 
   327 class PeerTransportError(Abort):
   410 class PeerTransportError(Abort):
   328     """Transport-level I/O error when communicating with a peer repo."""
   411     """Transport-level I/O error when communicating with a peer repo."""
   329 
   412 
       
   413 
   330 class InMemoryMergeConflictsError(Exception):
   414 class InMemoryMergeConflictsError(Exception):
   331     """Exception raised when merge conflicts arose during an in-memory merge."""
   415     """Exception raised when merge conflicts arose during an in-memory merge."""
   332     __bytes__ = _tobytes
   416 
       
   417     __bytes__ = _tobytes
       
   418 
   333 
   419 
   334 class WireprotoCommandError(Exception):
   420 class WireprotoCommandError(Exception):
   335     """Represents an error during execution of a wire protocol command.
   421     """Represents an error during execution of a wire protocol command.
   336 
   422 
   337     Should only be thrown by wire protocol version 2 commands.
   423     Should only be thrown by wire protocol version 2 commands.
   338 
   424 
   339     The error is a formatter string and an optional iterable of arguments.
   425     The error is a formatter string and an optional iterable of arguments.
   340     """
   426     """
       
   427 
   341     def __init__(self, message, args=None):
   428     def __init__(self, message, args=None):
   342         self.message = message
   429         self.message = message
   343         self.messageargs = args
   430         self.messageargs = args