34
33
# TODO: is there any value in providing the .args field used by standard
35
# python exceptions? A list of values with no names seems less useful
34
# python exceptions? A list of values with no names seems less useful
38
# TODO: Perhaps convert the exception to a string at the moment it's
37
# TODO: Perhaps convert the exception to a string at the moment it's
39
38
# constructed to make sure it will succeed. But that says nothing about
40
39
# exceptions that are never raised.
73
72
arguments can be given. The first is for generic "user" errors which
74
73
are not intended to be caught and so do not need a specific subclass.
75
74
The second case is for use with subclasses that provide a _fmt format
76
string to print the arguments.
75
string to print the arguments.
78
Keyword arguments are taken as parameters to the error, which can
79
be inserted into the format string template. It's recommended
80
that subclasses override the __init__ method to require specific
77
Keyword arguments are taken as parameters to the error, which can
78
be inserted into the format string template. It's recommended
79
that subclasses override the __init__ method to require specific
83
82
:param msg: If given, this is the literal complete text for the error,
484
486
# XXX: Should be unified with TransportError; they seem to represent the
486
488
# RBC 20060929: I think that unifiying with TransportError would be a mistake
487
# - this is finer than a TransportError - and more useful as such. It
489
# - this is finer than a TransportError - and more useful as such. It
488
490
# differentiates between 'transport has failed' and 'operation on a transport
490
492
class PathError(BzrError):
492
494
_fmt = "Generic path error: %(path)r%(extra)s)"
494
496
def __init__(self, path, extra=None):
1002
1004
class LockContention(LockError):
1004
_fmt = 'Could not acquire lock "%(lock)s"'
1006
_fmt = 'Could not acquire lock "%(lock)s": %(msg)s'
1005
1007
# TODO: show full url for lock, combining the transport and relative
1008
1010
internal_error = False
1010
def __init__(self, lock):
1012
def __init__(self, lock, msg=''):
1011
1013
self.lock = lock
1014
1017
class LockBroken(LockError):
1430
class SHA1KnitCorrupt(KnitCorrupt):
1432
_fmt = ("Knit %(filename)s corrupt: sha-1 of reconstructed text does not "
1433
"match expected sha-1. key %(key)s expected sha %(expected)s actual "
1436
def __init__(self, filename, actual, expected, key, content):
1437
KnitError.__init__(self)
1438
self.filename = filename
1439
self.actual = actual
1440
self.expected = expected
1442
self.content = content
1427
1445
class KnitDataStreamIncompatible(KnitError):
1428
1446
# Not raised anymore, as we can convert data streams. In future we may
1429
1447
# need it again for more exotic cases, so we're keeping it around for now.
1468
1486
self.options = options
1489
class RetryWithNewPacks(BzrError):
1490
"""Raised when we realize that the packs on disk have changed.
1492
This is meant as more of a signaling exception, to trap between where a
1493
local error occurred and the code that can actually handle the error and
1494
code that can retry appropriately.
1497
internal_error = True
1499
_fmt = ("Pack files have changed, reload and retry. context: %(context)s"
1502
def __init__(self, context, reload_occurred, exc_info):
1503
"""create a new RetryWithNewPacks error.
1505
:param reload_occurred: Set to True if we know that the packs have
1506
already been reloaded, and we are failing because of an in-memory
1507
cache miss. If set to True then we will ignore if a reload says
1508
nothing has changed, because we assume it has already reloaded. If
1509
False, then a reload with nothing changed will force an error.
1510
:param exc_info: The original exception traceback, so if there is a
1511
problem we can raise the original error (value from sys.exc_info())
1513
BzrError.__init__(self)
1514
self.reload_occurred = reload_occurred
1515
self.exc_info = exc_info
1516
self.orig_error = exc_info[1]
1517
# TODO: The global error handler should probably treat this by
1518
# raising/printing the original exception with a bit about
1519
# RetryWithNewPacks also not being caught
1522
class RetryAutopack(RetryWithNewPacks):
1523
"""Raised when we are autopacking and we find a missing file.
1525
Meant as a signaling exception, to tell the autopack code it should try
1529
internal_error = True
1531
_fmt = ("Pack files have changed, reload and try autopack again."
1532
" context: %(context)s %(orig_error)s")
1471
1535
class NoSuchExportFormat(BzrError):
1473
1537
_fmt = "Export format %(format)r not supported"
1475
1539
def __init__(self, format):
1530
1594
class SmartMessageHandlerError(InternalBzrError):
1532
_fmt = "The message handler raised an exception: %(exc_value)s."
1596
_fmt = ("The message handler raised an exception:\n"
1597
"%(traceback_text)s")
1534
1599
def __init__(self, exc_info):
1535
self.exc_type, self.exc_value, self.tb = exc_info
1601
self.exc_type, self.exc_value, self.exc_tb = exc_info
1602
self.exc_info = exc_info
1603
traceback_strings = traceback.format_exception(
1604
self.exc_type, self.exc_value, self.exc_tb)
1605
self.traceback_text = ''.join(traceback_strings)
1538
1608
# A set of semi-meaningful errors which can be thrown
1539
1609
class TransportNotPossible(TransportError):
1612
1684
_fmt = '%(source)s is%(permanently)s redirected to %(target)s'
1614
def __init__(self, source, target, is_permanent=False, qual_proto=None):
1686
def __init__(self, source, target, is_permanent=False):
1615
1687
self.source = source
1616
1688
self.target = target
1617
1689
if is_permanent:
1618
1690
self.permanently = ' permanently'
1620
1692
self.permanently = ''
1621
self._qualified_proto = qual_proto
1622
1693
TransportError.__init__(self)
1624
def _requalify_url(self, url):
1625
"""Restore the qualified proto in front of the url"""
1626
# When this exception is raised, source and target are in
1627
# user readable format. But some transports may use a
1628
# different proto (http+urllib:// will present http:// to
1629
# the user. If a qualified proto is specified, the code
1630
# trapping the exception can get the qualified urls to
1631
# properly handle the redirection themself (creating a
1632
# new transport object from the target url for example).
1633
# But checking that the scheme of the original and
1634
# redirected urls are the same can be tricky. (see the
1635
# FIXME in BzrDir.open_from_transport for the unique use
1637
if self._qualified_proto is None:
1640
# The TODO related to NotBranchError mention that doing
1641
# that kind of manipulation on the urls may not be the
1642
# exception object job. On the other hand, this object is
1643
# the interface between the code and the user so
1644
# presenting the urls in different ways is indeed its
1647
proto, netloc, path, query, fragment = urlparse.urlsplit(url)
1648
return urlparse.urlunsplit((self._qualified_proto, netloc, path,
1651
def get_source_url(self):
1652
return self._requalify_url(self.source)
1654
def get_target_url(self):
1655
return self._requalify_url(self.target)
1658
1696
class TooManyRedirections(TransportError):
2215
2248
self.text = text
2218
class MalformedHeader(BadBundle):
2251
class MalformedHeader(BadBundle):
2220
2253
_fmt = "Malformed bzr revision-bundle header: %(text)r"
2223
class MalformedPatches(BadBundle):
2256
class MalformedPatches(BadBundle):
2225
2258
_fmt = "Malformed patches in bzr revision-bundle: %(text)r"
2228
class MalformedFooter(BadBundle):
2261
class MalformedFooter(BadBundle):
2230
2263
_fmt = "Malformed footer in bzr revision-bundle: %(text)r"
2233
2266
class UnsupportedEOLMarker(BadBundle):
2235
_fmt = "End of line marker was not \\n in bzr revision-bundle"
2268
_fmt = "End of line marker was not \\n in bzr revision-bundle"
2237
2270
def __init__(self):
2238
# XXX: BadBundle's constructor assumes there's explanatory text,
2271
# XXX: BadBundle's constructor assumes there's explanatory text,
2239
2272
# but for this there is not
2240
2273
BzrError.__init__(self)
2243
2276
class IncompatibleBundleFormat(BzrError):
2245
2278
_fmt = "Bundle format %(bundle_format)s is incompatible with %(other)s"
2247
2280
def __init__(self, bundle_format, other):
2714
2748
_fmt = "'%(display_url)s' is already standalone."
2751
class AlreadyWithTrees(BzrDirError):
2753
_fmt = ("Shared repository '%(display_url)s' already creates "
2757
class AlreadyWithNoTrees(BzrDirError):
2759
_fmt = ("Shared repository '%(display_url)s' already doesn't create "
2717
2763
class ReconfigurationNotSupported(BzrDirError):
2719
2765
_fmt = "Requested reconfiguration of '%(display_url)s' is not supported."
2775
2821
class CommandAvailableInPlugin(StandardError):
2777
2823
internal_error = False
2779
2825
def __init__(self, cmd_name, plugin_metadata, provider):
2781
2827
self.plugin_metadata = plugin_metadata
2782
2828
self.cmd_name = cmd_name
2783
2829
self.provider = provider
2785
2831
def __str__(self):
2787
_fmt = ('"%s" is not a standard bzr command. \n'
2833
_fmt = ('"%s" is not a standard bzr command. \n'
2788
2834
'However, the following official plugin provides this command: %s\n'
2789
2835
'You can install it by going to: %s'
2790
% (self.cmd_name, self.plugin_metadata['name'],
2836
% (self.cmd_name, self.plugin_metadata['name'],
2791
2837
self.plugin_metadata['url']))
2796
2842
class NoPluginAvailable(BzrError):
2800
2846
class NotATerminal(BzrError):
2884
2930
"""A pre_change_branch_tip hook function may raise this to cleanly and
2885
2931
explicitly abort a change to a branch tip.
2888
2934
_fmt = u"Tip change rejected: %(msg)s"
2890
2936
def __init__(self, msg):
2940
class ShelfCorrupt(BzrError):
2942
_fmt = "Shelf corrupt."
2945
class NoSuchShelfId(BzrError):
2947
_fmt = 'No changes are shelved with id "%(shelf_id)d".'
2949
def __init__(self, shelf_id):
2950
BzrError.__init__(self, shelf_id=shelf_id)
2953
class InvalidShelfId(BzrError):
2955
_fmt = '"%(invalid_id)s" is not a valid shelf id, try a number instead.'
2957
def __init__(self, invalid_id):
2958
BzrError.__init__(self, invalid_id=invalid_id)
2961
class UserAbort(BzrError):
2963
_fmt = 'The user aborted the operation.'
2966
class MustHaveWorkingTree(BzrError):
2968
_fmt = ("Branching '%(url)s'(%(format)s) must create a working tree.")
2970
def __init__(self, format, url):
2971
BzrError.__init__(self, format=format, url=url)
2974
class NoSuchView(BzrError):
2975
"""A view does not exist.
2978
_fmt = u"No such view: %(view_name)s."
2980
def __init__(self, view_name):
2981
self.view_name = view_name
2984
class ViewsNotSupported(BzrError):
2985
"""Views are not supported by a tree format.
2988
_fmt = ("Views are not supported by %(tree)s;"
2989
" use 'bzr upgrade' to change your tree to a later format.")
2991
def __init__(self, tree):
2995
class FileOutsideView(BzrError):
2997
_fmt = ('Specified file "%(file_name)s" is outside the current view: '
3000
def __init__(self, file_name, view_files):
3001
self.file_name = file_name
3002
self.view_str = ", ".join(view_files)
3005
class UnresumableWriteGroup(BzrError):
3007
_fmt = ("Repository %(repository)s cannot resume write group "
3008
"%(write_groups)r: %(reason)s")
3010
internal_error = True
3012
def __init__(self, repository, write_groups, reason):
3013
self.repository = repository
3014
self.write_groups = write_groups
3015
self.reason = reason
3018
class UnsuspendableWriteGroup(BzrError):
3020
_fmt = ("Repository %(repository)s cannot suspend a write group.")
3022
internal_error = True
3024
def __init__(self, repository):
3025
self.repository = repository