error.py
692 lines
| 17.8 KiB
| text/x-python
|
PythonLexer
/ mercurial / error.py
Martin Geisler
|
r8226 | # error.py - Mercurial exceptions | ||
# | ||||
Raphaël Gomès
|
r47575 | # Copyright 2005-2008 Olivia Mackall <olivia@selenic.com> | ||
Martin Geisler
|
r8226 | # | ||
# This software may be used and distributed according to the terms of the | ||||
Matt Mackall
|
r10263 | # GNU General Public License version 2 or any later version. | ||
Matt Mackall
|
r7633 | |||
Martin Geisler
|
r8227 | """Mercurial exceptions. | ||
This allows us to catch exceptions at higher levels without forcing | ||||
imports. | ||||
""" | ||||
Matt Harbison
|
r52756 | from __future__ import annotations | ||
Gregory Szorc
|
r25945 | |||
Martin von Zweigbergk
|
r46494 | import difflib | ||
r52178 | from typing import ( | |||
AnyStr, | ||||
Iterable, | ||||
List, | ||||
Optional, | ||||
Sequence, | ||||
Union, | ||||
) | ||||
Yuya Nishihara
|
r32616 | # Do not import anything but pycompat here, please | ||
from . import pycompat | ||||
r52178 | ||||
r52180 | def _tobytes(exc) -> bytes: | |||
Yuya Nishihara
|
r32616 | """Byte-stringify exception in the same way as BaseException_str()""" | ||
if not exc.args: | ||||
return b'' | ||||
if len(exc.args) == 1: | ||||
return pycompat.bytestr(exc.args[0]) | ||||
return b'(%s)' % b', '.join(b"'%s'" % pycompat.bytestr(a) for a in exc.args) | ||||
Matt Mackall
|
r7633 | |||
Augie Fackler
|
r43346 | |||
Gregory Szorc
|
r49801 | class Hint: | ||
Yuya Nishihara
|
r29509 | """Mix-in to provide a hint of an error | ||
Yuya Nishihara
|
r29510 | This should come first in the inheritance list to consume a hint and | ||
pass remaining arguments to the exception class. | ||||
Yuya Nishihara
|
r29509 | """ | ||
Augie Fackler
|
r43346 | |||
Jordi Gutiérrez Hermoso
|
r25248 | def __init__(self, *args, **kw): | ||
r52181 | self.hint: Optional[bytes] = kw.pop('hint', None) | |||
Yuya Nishihara
|
r29510 | super(Hint, self).__init__(*args, **kw) | ||
Jordi Gutiérrez Hermoso
|
r25248 | |||
Augie Fackler
|
r43346 | |||
Martin von Zweigbergk
|
r48072 | class Error(Hint, Exception): | ||
"""Base class for Mercurial errors.""" | ||||
Martin von Zweigbergk
|
r48070 | |||
Martin von Zweigbergk
|
r48085 | coarse_exit_code = None | ||
detailed_exit_code = None | ||||
r52180 | def __init__(self, message: bytes, hint: Optional[bytes] = None) -> None: | |||
Martin von Zweigbergk
|
r48070 | self.message = message | ||
self.hint = hint | ||||
# Pass the message into the Exception constructor to help extensions | ||||
# that look for exc.args[0]. | ||||
Exception.__init__(self, message) | ||||
def __bytes__(self): | ||||
return self.message | ||||
r52180 | def __str__(self) -> str: | |||
Gregory Szorc
|
r49744 | # the output would be unreadable if the message was translated, | ||
# but do not replace it with encoding.strfromlocal(), which | ||||
# may raise another exception. | ||||
return pycompat.sysstr(self.__bytes__()) | ||||
Martin von Zweigbergk
|
r48070 | |||
r52180 | def format(self) -> bytes: | |||
Martin von Zweigbergk
|
r48070 | from .i18n import _ | ||
message = _(b"abort: %s\n") % self.message | ||||
if self.hint: | ||||
message += _(b"(%s)\n") % self.hint | ||||
return message | ||||
Martin von Zweigbergk
|
r48072 | class Abort(Error): | ||
"""Raised if a command needs to print an error and exit.""" | ||||
Martin von Zweigbergk
|
r48075 | class StorageError(Error): | ||
Gregory Szorc
|
r39812 | """Raised when an error occurs in a storage layer. | ||
Usually subclassed by a storage-specific exception. | ||||
""" | ||||
Augie Fackler
|
r43346 | |||
Martin von Zweigbergk
|
r48085 | detailed_exit_code = 50 | ||
Gregory Szorc
|
r39812 | |||
Augie Fackler
|
r43346 | |||
Gregory Szorc
|
r39812 | class RevlogError(StorageError): | ||
Martin von Zweigbergk
|
r46360 | pass | ||
Matt Mackall
|
r7633 | |||
Augie Fackler
|
r43346 | |||
r43302 | class SidedataHashError(RevlogError): | |||
r52180 | def __init__(self, key: int, expected: bytes, got: bytes) -> None: | |||
Raphaël Gomès
|
r47370 | self.hint = None | ||
r43302 | self.sidedatakey = key | |||
self.expecteddigest = expected | ||||
self.actualdigest = got | ||||
Augie Fackler
|
r43346 | |||
Pierre-Yves David
|
r23014 | class FilteredIndexError(IndexError): | ||
Yuya Nishihara
|
r32616 | __bytes__ = _tobytes | ||
Pierre-Yves David
|
r23014 | |||
Augie Fackler
|
r43346 | |||
Matt Mackall
|
r7633 | class LookupError(RevlogError, KeyError): | ||
r52180 | def __init__(self, name: bytes, index: bytes, message: bytes) -> None: | |||
Matt Mackall
|
r7633 | self.name = name | ||
Martin von Zweigbergk
|
r24038 | self.index = index | ||
Siddharth Agarwal
|
r24137 | # this can't be called 'message' because at least some installs of | ||
# Python 2.6+ complain about the 'message' property being deprecated | ||||
self.lookupmessage = message | ||||
Augie Fackler
|
r36559 | if isinstance(name, bytes) and len(name) == 20: | ||
Pulkit Goyal
|
r47397 | from .node import hex | ||
Augie Fackler
|
r43346 | |||
Pulkit Goyal
|
r47397 | name = hex(name) | ||
Yuya Nishihara
|
r46075 | # if name is a binary node, it can be None | ||
RevlogError.__init__( | ||||
self, b'%s@%s: %s' % (index, pycompat.bytestr(name), message) | ||||
) | ||||
Matt Mackall
|
r7633 | |||
Yuya Nishihara
|
r32616 | def __bytes__(self): | ||
return RevlogError.__bytes__(self) | ||||
Matt Mackall
|
r7633 | def __str__(self): | ||
return RevlogError.__str__(self) | ||||
Matt Mackall
|
r7636 | |||
Augie Fackler
|
r43346 | |||
Martin von Zweigbergk
|
r38877 | class AmbiguousPrefixLookupError(LookupError): | ||
pass | ||||
Augie Fackler
|
r43346 | |||
Pierre-Yves David
|
r23015 | class FilteredLookupError(LookupError): | ||
pass | ||||
Augie Fackler
|
r43346 | |||
Takumi IINO
|
r18855 | class ManifestLookupError(LookupError): | ||
pass | ||||
Augie Fackler
|
r43346 | |||
Matt Mackall
|
r11287 | class CommandError(Exception): | ||
Matt Mackall
|
r7636 | """Exception raised on errors in parsing the command line.""" | ||
Augie Fackler
|
r43346 | |||
r52180 | def __init__(self, command: Optional[bytes], message: bytes) -> None: | |||
Martin von Zweigbergk
|
r46270 | self.command = command | ||
self.message = message | ||||
super(CommandError, self).__init__() | ||||
Yuya Nishihara
|
r32616 | __bytes__ = _tobytes | ||
Matt Mackall
|
r7637 | |||
Augie Fackler
|
r43346 | |||
Martin von Zweigbergk
|
r46269 | class UnknownCommand(Exception): | ||
"""Exception raised if command is not in the command table.""" | ||||
r52180 | def __init__( | |||
self, | ||||
command: bytes, | ||||
all_commands: Optional[List[bytes]] = None, | ||||
) -> None: | ||||
Martin von Zweigbergk
|
r46272 | self.command = command | ||
self.all_commands = all_commands | ||||
super(UnknownCommand, self).__init__() | ||||
Martin von Zweigbergk
|
r46269 | __bytes__ = _tobytes | ||
class AmbiguousCommand(Exception): | ||||
"""Exception raised if command shortcut matches more than one command.""" | ||||
r52180 | def __init__(self, prefix: bytes, matches: List[bytes]) -> None: | |||
Martin von Zweigbergk
|
r46271 | self.prefix = prefix | ||
self.matches = matches | ||||
super(AmbiguousCommand, self).__init__() | ||||
Martin von Zweigbergk
|
r46269 | __bytes__ = _tobytes | ||
Martin von Zweigbergk
|
r46429 | class WorkerError(Exception): | ||
"""Exception raised when a worker process dies.""" | ||||
r52180 | def __init__(self, status_code: int) -> None: | |||
Martin von Zweigbergk
|
r46429 | self.status_code = status_code | ||
Martin von Zweigbergk
|
r46515 | # Pass status code to superclass just so it becomes part of __bytes__ | ||
super(WorkerError, self).__init__(status_code) | ||||
__bytes__ = _tobytes | ||||
Martin von Zweigbergk
|
r46429 | |||
Martin von Zweigbergk
|
r48071 | class InterventionRequired(Abort): | ||
Augie Fackler
|
r18931 | """Exception raised when a command requires human intervention.""" | ||
Augie Fackler
|
r43346 | |||
Martin von Zweigbergk
|
r48085 | coarse_exit_code = 1 | ||
detailed_exit_code = 240 | ||||
Martin von Zweigbergk
|
r48071 | |||
r52180 | def format(self) -> bytes: | |||
Martin von Zweigbergk
|
r48071 | from .i18n import _ | ||
message = _(b"%s\n") % self.message | ||||
if self.hint: | ||||
message += _(b"(%s)\n") % self.hint | ||||
return message | ||||
Augie Fackler
|
r18931 | |||
Augie Fackler
|
r43346 | |||
Daniel Ploch
|
r45711 | class ConflictResolutionRequired(InterventionRequired): | ||
"""Exception raised when a continuable command required merge conflict resolution.""" | ||||
r52180 | def __init__(self, opname: bytes) -> None: | |||
Daniel Ploch
|
r45711 | from .i18n import _ | ||
self.opname = opname | ||||
InterventionRequired.__init__( | ||||
self, | ||||
_( | ||||
b"unresolved conflicts (see 'hg resolve', then 'hg %s --continue')" | ||||
) | ||||
% opname, | ||||
) | ||||
Martin von Zweigbergk
|
r46431 | class InputError(Abort): | ||
"""Indicates that the user made an error in their input. | ||||
Examples: Invalid command, invalid flags, invalid revision. | ||||
""" | ||||
Martin von Zweigbergk
|
r48085 | detailed_exit_code = 10 | ||
Martin von Zweigbergk
|
r48069 | |||
Martin von Zweigbergk
|
r46431 | |||
Martin von Zweigbergk
|
r46444 | class StateError(Abort): | ||
"""Indicates that the operation might work if retried in a different state. | ||||
Examples: Unresolved merge conflicts, unfinished operations. | ||||
""" | ||||
Martin von Zweigbergk
|
r48085 | detailed_exit_code = 20 | ||
Martin von Zweigbergk
|
r48069 | |||
Martin von Zweigbergk
|
r46444 | |||
Martin von Zweigbergk
|
r46489 | class CanceledError(Abort): | ||
"""Indicates that the user canceled the operation. | ||||
Examples: Close commit editor with error status, quit chistedit. | ||||
""" | ||||
Martin von Zweigbergk
|
r48085 | detailed_exit_code = 250 | ||
Martin von Zweigbergk
|
r48069 | |||
Martin von Zweigbergk
|
r46489 | |||
Martin von Zweigbergk
|
r46527 | class SecurityError(Abort): | ||
"""Indicates that some aspect of security failed. | ||||
Examples: Bad server credentials, expired local credentials for network | ||||
filesystem, mismatched GPG signature, DoS protection. | ||||
""" | ||||
Martin von Zweigbergk
|
r48085 | detailed_exit_code = 150 | ||
Martin von Zweigbergk
|
r48069 | |||
Martin von Zweigbergk
|
r46527 | |||
Siddharth Agarwal
|
r26692 | class HookLoadError(Abort): | ||
"""raised when loading a hook fails, aborting an operation | ||||
Exists to allow more specialized catching.""" | ||||
Augie Fackler
|
r43346 | |||
Pierre-Yves David
|
r23415 | class HookAbort(Abort): | ||
"""raised when a validation hook fails, aborting an operation | ||||
Exists to allow more specialized catching.""" | ||||
Martin von Zweigbergk
|
r48085 | detailed_exit_code = 40 | ||
Martin von Zweigbergk
|
r48069 | |||
Augie Fackler
|
r43346 | |||
Matt Mackall
|
r11288 | class ConfigError(Abort): | ||
Mike Edgar
|
r22359 | """Exception raised when parsing config files""" | ||
Matt Mackall
|
r8144 | |||
Martin von Zweigbergk
|
r48085 | detailed_exit_code = 30 | ||
r52180 | def __init__( | |||
self, | ||||
message: bytes, | ||||
location: Optional[bytes] = None, | ||||
hint: Optional[bytes] = None, | ||||
) -> None: | ||||
Martin von Zweigbergk
|
r48085 | super(ConfigError, self).__init__(message, hint=hint) | ||
Martin von Zweigbergk
|
r46506 | self.location = location | ||
r52180 | def format(self) -> bytes: | |||
Martin von Zweigbergk
|
r46506 | from .i18n import _ | ||
if self.location is not None: | ||||
message = _(b"config error at %s: %s\n") % ( | ||||
pycompat.bytestr(self.location), | ||||
self.message, | ||||
) | ||||
else: | ||||
message = _(b"config error: %s\n") % self.message | ||||
if self.hint: | ||||
message += _(b"(%s)\n") % self.hint | ||||
return message | ||||
Augie Fackler
|
r43346 | |||
Pierre-Yves David
|
r26683 | class UpdateAbort(Abort): | ||
"""Raised when an update is aborted for destination issue""" | ||||
Augie Fackler
|
r43346 | |||
Pierre-Yves David
|
r28141 | class MergeDestAbort(Abort): | ||
"""Raised when an update is aborted for destination issues""" | ||||
Augie Fackler
|
r43346 | |||
Pierre-Yves David
|
r28141 | class NoMergeDestAbort(MergeDestAbort): | ||
"""Raised when an update is aborted because there is nothing to merge""" | ||||
Augie Fackler
|
r43346 | |||
Pierre-Yves David
|
r28141 | class ManyMergeDestAbort(MergeDestAbort): | ||
Mads Kiilerich
|
r30332 | """Raised when an update is aborted because destination is ambiguous""" | ||
Pierre-Yves David
|
r28141 | |||
Augie Fackler
|
r43346 | |||
Siddharth Agarwal
|
r26896 | class ResponseExpected(Abort): | ||
"""Raised when an EOF is received for a prompt""" | ||||
Augie Fackler
|
r43346 | |||
Siddharth Agarwal
|
r26896 | def __init__(self): | ||
from .i18n import _ | ||||
Augie Fackler
|
r43346 | |||
Augie Fackler
|
r43347 | Abort.__init__(self, _(b'response expected')) | ||
Siddharth Agarwal
|
r26896 | |||
Augie Fackler
|
r43346 | |||
Martin von Zweigbergk
|
r47738 | class RemoteError(Abort): | ||
"""Exception raised when interacting with a remote repo fails""" | ||||
Martin von Zweigbergk
|
r48085 | detailed_exit_code = 100 | ||
Martin von Zweigbergk
|
r48069 | |||
Martin von Zweigbergk
|
r47738 | |||
class OutOfBandError(RemoteError): | ||||
Mike Edgar
|
r22359 | """Exception raised when a remote repo reports failure""" | ||
Augie Fackler
|
r43346 | |||
r52180 | def __init__( | |||
self, | ||||
message: Optional[bytes] = None, | ||||
hint: Optional[bytes] = None, | ||||
): | ||||
Martin von Zweigbergk
|
r47737 | from .i18n import _ | ||
Martin von Zweigbergk
|
r47743 | if message: | ||
Martin von Zweigbergk
|
r47737 | # Abort.format() adds a trailing newline | ||
Martin von Zweigbergk
|
r47743 | message = _(b"remote error:\n%s") % message.rstrip(b'\n') | ||
Martin von Zweigbergk
|
r47737 | else: | ||
message = _(b"remote error") | ||||
Martin von Zweigbergk
|
r47743 | super(OutOfBandError, self).__init__(message, hint=hint) | ||
Andrew Pritchard
|
r15017 | |||
Augie Fackler
|
r43346 | |||
Martin von Zweigbergk
|
r46499 | class ParseError(Abort): | ||
Augie Fackler
|
r24040 | """Raised when parsing config files and {rev,file}sets (msg[, pos])""" | ||
Augie Fackler
|
r43346 | |||
Martin von Zweigbergk
|
r48085 | detailed_exit_code = 10 | ||
r52180 | def __init__( | |||
self, | ||||
message: bytes, | ||||
location: Optional[Union[bytes, int]] = None, | ||||
hint: Optional[bytes] = None, | ||||
): | ||||
Martin von Zweigbergk
|
r48085 | super(ParseError, self).__init__(message, hint=hint) | ||
Martin von Zweigbergk
|
r46361 | self.location = location | ||
r52180 | def format(self) -> bytes: | |||
Martin von Zweigbergk
|
r46496 | from .i18n import _ | ||
if self.location is not None: | ||||
message = _(b"hg: parse error at %s: %s\n") % ( | ||||
pycompat.bytestr(self.location), | ||||
self.message, | ||||
) | ||||
else: | ||||
message = _(b"hg: parse error: %s\n") % self.message | ||||
if self.hint: | ||||
message += _(b"(%s)\n") % self.hint | ||||
return message | ||||
Augie Fackler
|
r43346 | |||
Yuya Nishihara
|
r34252 | class PatchError(Exception): | ||
__bytes__ = _tobytes | ||||
Augie Fackler
|
r43346 | |||
Martin von Zweigbergk
|
r49186 | class PatchParseError(PatchError): | ||
__bytes__ = _tobytes | ||||
class PatchApplicationError(PatchError): | ||||
__bytes__ = _tobytes | ||||
r52180 | def getsimilar(symbols: Iterable[bytes], value: bytes) -> List[bytes]: | |||
Martin von Zweigbergk
|
r46494 | sim = lambda x: difflib.SequenceMatcher(None, value, x).ratio() | ||
# The cutoff for similarity here is pretty arbitrary. It should | ||||
# probably be investigated and tweaked. | ||||
return [s for s in symbols if sim(s) > 0.6] | ||||
r52180 | def similarity_hint(similar: List[bytes]) -> Optional[bytes]: | |||
Martin von Zweigbergk
|
r46494 | from .i18n import _ | ||
if len(similar) == 1: | ||||
return _(b"did you mean %s?") % similar[0] | ||||
elif similar: | ||||
ss = b", ".join(sorted(similar)) | ||||
return _(b"did you mean one of %s?") % ss | ||||
else: | ||||
return None | ||||
Augie Fackler
|
r24217 | class UnknownIdentifier(ParseError): | ||
"""Exception raised when a {rev,file}set references an unknown identifier""" | ||||
r52180 | def __init__(self, function: bytes, symbols: Iterable[bytes]) -> None: | |||
Gregory Szorc
|
r25945 | from .i18n import _ | ||
Augie Fackler
|
r43346 | |||
Martin von Zweigbergk
|
r46495 | similar = getsimilar(symbols, function) | ||
hint = similarity_hint(similar) | ||||
ParseError.__init__( | ||||
self, _(b"unknown identifier: %s") % function, hint=hint | ||||
) | ||||
Augie Fackler
|
r24217 | |||
Augie Fackler
|
r43346 | |||
Yuya Nishihara
|
r29509 | class RepoError(Hint, Exception): | ||
Yuya Nishihara
|
r32616 | __bytes__ = _tobytes | ||
Matt Mackall
|
r7637 | |||
Augie Fackler
|
r43346 | |||
Matt Mackall
|
r9423 | class RepoLookupError(RepoError): | ||
pass | ||||
Augie Fackler
|
r43346 | |||
Pierre-Yves David
|
r23016 | class FilteredRepoLookupError(RepoLookupError): | ||
pass | ||||
Augie Fackler
|
r43346 | |||
Matt Mackall
|
r7637 | class CapabilityError(RepoError): | ||
pass | ||||
Matt Mackall
|
r7640 | |||
Augie Fackler
|
r43346 | |||
Adrian Buehlmann
|
r13447 | class RequirementError(RepoError): | ||
"""Exception raised if .hg/requires has an unknown entry.""" | ||||
Augie Fackler
|
r43346 | |||
Bryan O'Sullivan
|
r31959 | class StdioError(IOError): | ||
"""Raised if I/O to stdout or stderr fails""" | ||||
r52180 | def __init__(self, err: IOError) -> None: | |||
Bryan O'Sullivan
|
r31959 | IOError.__init__(self, err.errno, err.strerror) | ||
Yuya Nishihara
|
r32616 | # no __bytes__() because error message is derived from the standard IOError | ||
Augie Fackler
|
r43346 | |||
Siddharth Agarwal
|
r26985 | class UnsupportedMergeRecords(Abort): | ||
r52180 | def __init__(self, recordtypes: Iterable[bytes]) -> None: | |||
Siddharth Agarwal
|
r26985 | from .i18n import _ | ||
Augie Fackler
|
r43346 | |||
Siddharth Agarwal
|
r26985 | self.recordtypes = sorted(recordtypes) | ||
Augie Fackler
|
r43347 | s = b' '.join(self.recordtypes) | ||
Siddharth Agarwal
|
r26985 | Abort.__init__( | ||
Augie Fackler
|
r43346 | self, | ||
Augie Fackler
|
r43347 | _(b'unsupported merge state records: %s') % s, | ||
Augie Fackler
|
r43346 | hint=_( | ||
Augie Fackler
|
r43347 | b'see https://mercurial-scm.org/wiki/MergeStateRecords for ' | ||
b'more information' | ||||
Augie Fackler
|
r43346 | ), | ||
) | ||||
Siddharth Agarwal
|
r26985 | |||
r32591 | class UnknownVersion(Abort): | |||
Augie Fackler
|
r46554 | """generic exception for aborting from an encounter with an unknown version""" | ||
r32591 | ||||
r52180 | def __init__( | |||
self, | ||||
msg: bytes, | ||||
hint: Optional[bytes] = None, | ||||
version: Optional[bytes] = None, | ||||
) -> None: | ||||
r32591 | self.version = version | |||
super(UnknownVersion, self).__init__(msg, hint=hint) | ||||
Augie Fackler
|
r43346 | |||
Matt Mackall
|
r7640 | class LockError(IOError): | ||
r52180 | def __init__( | |||
self, | ||||
errno: int, | ||||
strerror: str, | ||||
filename: bytes, | ||||
desc: Optional[bytes], | ||||
) -> None: | ||||
Matt Mackall
|
r7640 | IOError.__init__(self, errno, strerror, filename) | ||
self.desc = desc | ||||
Yuya Nishihara
|
r32616 | # no __bytes__() because error message is derived from the standard IOError | ||
Augie Fackler
|
r43346 | |||
Matt Mackall
|
r7640 | class LockHeld(LockError): | ||
r52180 | def __init__( | |||
self, | ||||
errno: int, | ||||
filename: bytes, | ||||
desc: Optional[bytes], | ||||
locker, | ||||
): | ||||
r52179 | LockError.__init__(self, errno, 'Lock held', filename, desc) | |||
r52180 | self.filename: bytes = filename | |||
Matt Mackall
|
r7640 | self.locker = locker | ||
Augie Fackler
|
r43346 | |||
Matt Mackall
|
r7640 | class LockUnavailable(LockError): | ||
pass | ||||
Matt Mackall
|
r7641 | |||
Augie Fackler
|
r43346 | |||
Siddharth Agarwal
|
r26355 | # LockError is for errors while acquiring the lock -- this is unrelated | ||
Siddharth Agarwal
|
r26438 | class LockInheritanceContractViolation(RuntimeError): | ||
Yuya Nishihara
|
r32616 | __bytes__ = _tobytes | ||
Siddharth Agarwal
|
r26355 | |||
Augie Fackler
|
r43346 | |||
Matt Mackall
|
r7641 | class ResponseError(Exception): | ||
"""Raised to print an error with part of output and exit.""" | ||||
Augie Fackler
|
r43346 | |||
Yuya Nishihara
|
r32616 | __bytes__ = _tobytes | ||
Matt Mackall
|
r7641 | |||
Augie Fackler
|
r43346 | |||
Matt Mackall
|
r7644 | # derived from KeyboardInterrupt to simplify some breakout code | ||
class SignalInterrupt(KeyboardInterrupt): | ||||
"""Exception raised on SIGTERM and SIGHUP.""" | ||||
Matt Mackall
|
r7646 | |||
Augie Fackler
|
r43346 | |||
Matt Mackall
|
r7646 | class SignatureError(Exception): | ||
Yuya Nishihara
|
r32616 | __bytes__ = _tobytes | ||
Pierre-Yves David
|
r21184 | |||
Augie Fackler
|
r43346 | |||
Pierre-Yves David
|
r21184 | class PushRaced(RuntimeError): | ||
"""An exception raised during unbundling that indicate a push race""" | ||||
Augie Fackler
|
r43346 | |||
Yuya Nishihara
|
r32616 | __bytes__ = _tobytes | ||
Pierre-Yves David
|
r21184 | |||
Augie Fackler
|
r43346 | |||
Yuya Nishihara
|
r32340 | class ProgrammingError(Hint, RuntimeError): | ||
Jun Wu
|
r30585 | """Raised if a mercurial (core or extension) developer made a mistake""" | ||
Augie Fackler
|
r39615 | |||
r52180 | def __init__(self, msg: AnyStr, *args, **kwargs): | |||
Yuya Nishihara
|
r39632 | # On Python 3, turn the message back into a string since this is | ||
# an internal-only error that won't be printed except in a | ||||
# stack traces. | ||||
msg = pycompat.sysstr(msg) | ||||
Augie Fackler
|
r39615 | super(ProgrammingError, self).__init__(msg, *args, **kwargs) | ||
Yuya Nishihara
|
r32616 | __bytes__ = _tobytes | ||
Jun Wu
|
r30573 | |||
Augie Fackler
|
r43346 | |||
Pulkit Goyal
|
r32401 | class WdirUnsupported(Exception): | ||
"""An exception which is raised when 'wdir()' is not supported""" | ||||
Augie Fackler
|
r43346 | |||
Yuya Nishihara
|
r32616 | __bytes__ = _tobytes | ||
Pulkit Goyal
|
r32401 | |||
Augie Fackler
|
r43346 | |||
Pierre-Yves David
|
r21618 | # bundle2 related errors | ||
class BundleValueError(ValueError): | ||||
Pierre-Yves David
|
r21621 | """error raised when bundle2 cannot be processed""" | ||
Augie Fackler
|
r43346 | |||
Yuya Nishihara
|
r32616 | __bytes__ = _tobytes | ||
Pierre-Yves David
|
r21620 | |||
Augie Fackler
|
r43346 | |||
Pierre-Yves David
|
r26393 | class BundleUnknownFeatureError(BundleValueError): | ||
Pierre-Yves David
|
r26394 | def __init__(self, parttype=None, params=(), values=()): | ||
Pierre-Yves David
|
r21620 | self.parttype = parttype | ||
Pierre-Yves David
|
r21621 | self.params = params | ||
Pierre-Yves David
|
r26394 | self.values = values | ||
Pierre-Yves David
|
r21627 | if self.parttype is None: | ||
Augie Fackler
|
r43347 | msg = b'Stream Parameter' | ||
Pierre-Yves David
|
r21627 | else: | ||
msg = parttype | ||||
Pierre-Yves David
|
r26394 | entries = self.params | ||
if self.params and self.values: | ||||
assert len(self.params) == len(self.values) | ||||
entries = [] | ||||
for idx, par in enumerate(self.params): | ||||
val = self.values[idx] | ||||
if val is None: | ||||
entries.append(val) | ||||
else: | ||||
Augie Fackler
|
r43347 | entries.append(b"%s=%r" % (par, pycompat.maybebytestr(val))) | ||
Pierre-Yves David
|
r26394 | if entries: | ||
Augie Fackler
|
r43347 | msg = b'%s - %s' % (msg, b', '.join(entries)) | ||
Matt Harbison
|
r47661 | ValueError.__init__(self, msg) # TODO: convert to str? | ||
Pierre-Yves David
|
r21618 | |||
Augie Fackler
|
r43346 | |||
Pierre-Yves David
|
r21618 | class ReadOnlyPartError(RuntimeError): | ||
"""error raised when code tries to alter a part being generated""" | ||||
Augie Fackler
|
r43346 | |||
Yuya Nishihara
|
r32616 | __bytes__ = _tobytes | ||
Pierre-Yves David
|
r21618 | |||
Augie Fackler
|
r43346 | |||
Pierre-Yves David
|
r25484 | class PushkeyFailed(Abort): | ||
"""error raised when a pushkey part failed to update a value""" | ||||
Augie Fackler
|
r43346 | def __init__( | ||
self, partid, namespace=None, key=None, new=None, old=None, ret=None | ||||
): | ||||
Pierre-Yves David
|
r25484 | self.partid = partid | ||
self.namespace = namespace | ||||
self.key = key | ||||
self.new = new | ||||
self.old = old | ||||
self.ret = ret | ||||
# no i18n expected to be processed into a better message | ||||
Augie Fackler
|
r43346 | Abort.__init__( | ||
Augie Fackler
|
r43347 | self, b'failed to update value for "%s/%s"' % (namespace, key) | ||
Augie Fackler
|
r43346 | ) | ||
Pierre-Yves David
|
r25484 | |||
Gregory Szorc
|
r39813 | class CensoredNodeError(StorageError): | ||
Mike Edgar
|
r24190 | """error raised when content verification fails on a censored node | ||
Mike Edgar
|
r22595 | |||
Mike Edgar
|
r24190 | Also contains the tombstone data substituted for the uncensored data. | ||
""" | ||||
r52180 | def __init__(self, filename: bytes, node: bytes, tombstone: bytes): | |||
Gregory Szorc
|
r25945 | from .node import short | ||
Augie Fackler
|
r43346 | |||
Augie Fackler
|
r43347 | StorageError.__init__(self, b'%s:%s' % (filename, short(node))) | ||
Mike Edgar
|
r24190 | self.tombstone = tombstone | ||
Mike Edgar
|
r24120 | |||
Augie Fackler
|
r43346 | |||
Gregory Szorc
|
r39813 | class CensoredBaseError(StorageError): | ||
Mike Edgar
|
r24120 | """error raised when a delta is rejected because its base is censored | ||
A delta based on a censored revision must be formed as single patch | ||||
operation which replaces the entire base with new content. This ensures | ||||
the delta may be applied by clones which have not censored the base. | ||||
""" | ||||
Gregory Szorc
|
r26640 | |||
Augie Fackler
|
r43346 | |||
Gregory Szorc
|
r26640 | class InvalidBundleSpecification(Exception): | ||
"""error raised when a bundle specification is invalid. | ||||
This is used for syntax errors as opposed to support errors. | ||||
""" | ||||
Augie Fackler
|
r43346 | |||
Yuya Nishihara
|
r32616 | __bytes__ = _tobytes | ||
Gregory Szorc
|
r26640 | |||
Augie Fackler
|
r43346 | |||
Gregory Szorc
|
r26640 | class UnsupportedBundleSpecification(Exception): | ||
"""error raised when a bundle specification is not supported.""" | ||||
Augie Fackler
|
r43346 | |||
Yuya Nishihara
|
r32616 | __bytes__ = _tobytes | ||
Kostia Balytskyi
|
r29536 | |||
Augie Fackler
|
r43346 | |||
Kostia Balytskyi
|
r29536 | class CorruptedState(Exception): | ||
"""error raised when a command is not able to read its state from file""" | ||||
Augie Fackler
|
r43346 | |||
Yuya Nishihara
|
r32616 | __bytes__ = _tobytes | ||
Gregory Szorc
|
r32002 | |||
Augie Fackler
|
r43346 | |||
Raphaël Gomès
|
r51553 | class CorruptedDirstate(Exception): | ||
"""error raised the dirstate appears corrupted on-disk. It may be due to | ||||
a dirstate version mismatch (i.e. expecting v2 and finding v1 on disk).""" | ||||
__bytes__ = _tobytes | ||||
Gregory Szorc
|
r32023 | class PeerTransportError(Abort): | ||
"""Transport-level I/O error when communicating with a peer repo.""" | ||||
Phil Cohen
|
r35104 | |||
Augie Fackler
|
r43346 | |||
Phil Cohen
|
r35104 | class InMemoryMergeConflictsError(Exception): | ||
"""Exception raised when merge conflicts arose during an in-memory merge.""" | ||||
Augie Fackler
|
r43346 | |||
Phil Cohen
|
r35104 | __bytes__ = _tobytes | ||
Gregory Szorc
|
r39595 | |||
Augie Fackler
|
r43346 | |||
Gregory Szorc
|
r39595 | class WireprotoCommandError(Exception): | ||
"""Represents an error during execution of a wire protocol command. | ||||
Should only be thrown by wire protocol version 2 commands. | ||||
The error is a formatter string and an optional iterable of arguments. | ||||
""" | ||||
Augie Fackler
|
r43346 | |||
r52180 | def __init__( | |||
self, | ||||
message: bytes, | ||||
args: Optional[Sequence[bytes]] = None, | ||||
) -> None: | ||||
Gregory Szorc
|
r39595 | self.message = message | ||
self.messageargs = args | ||||