1486
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")
1489
1535
class NoSuchExportFormat(BzrError):
1491
1537
_fmt = "Export format %(format)r not supported"
1630
1676
_fmt = '%(source)s is%(permanently)s redirected to %(target)s'
1632
def __init__(self, source, target, is_permanent=False, qual_proto=None):
1678
def __init__(self, source, target, is_permanent=False):
1633
1679
self.source = source
1634
1680
self.target = target
1635
1681
if is_permanent:
1636
1682
self.permanently = ' permanently'
1638
1684
self.permanently = ''
1639
self._qualified_proto = qual_proto
1640
1685
TransportError.__init__(self)
1642
def _requalify_url(self, url):
1643
"""Restore the qualified proto in front of the url"""
1644
# When this exception is raised, source and target are in
1645
# user readable format. But some transports may use a
1646
# different proto (http+urllib:// will present http:// to
1647
# the user. If a qualified proto is specified, the code
1648
# trapping the exception can get the qualified urls to
1649
# properly handle the redirection themself (creating a
1650
# new transport object from the target url for example).
1651
# But checking that the scheme of the original and
1652
# redirected urls are the same can be tricky. (see the
1653
# FIXME in BzrDir.open_from_transport for the unique use
1655
if self._qualified_proto is None:
1658
# The TODO related to NotBranchError mention that doing
1659
# that kind of manipulation on the urls may not be the
1660
# exception object job. On the other hand, this object is
1661
# the interface between the code and the user so
1662
# presenting the urls in different ways is indeed its
1665
proto, netloc, path, query, fragment = urlparse.urlsplit(url)
1666
return urlparse.urlunsplit((self._qualified_proto, netloc, path,
1669
def get_source_url(self):
1670
return self._requalify_url(self.source)
1672
def get_target_url(self):
1673
return self._requalify_url(self.target)
1676
1688
class TooManyRedirections(TransportError):