1
1
# Copyright (C) 2005, 2006 Canonical
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
11
# GNU General Public License for more details.
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
"""Exceptions for bzr, and reporting of them.
19
There are 3 different classes of error:
21
* KeyboardInterrupt, and OSError with EPIPE - the program terminates
22
with an appropriate short message
24
* User errors, indicating a problem caused by the user such as a bad URL.
25
These are printed in a short form.
27
* Internal unexpected errors, including most Python builtin errors
28
and some raised from inside bzr. These are printed with a full
29
traceback and an invitation to report the bug.
31
19
Exceptions are caught at a high level to report errors to the user, and
32
20
might also be caught inside the program. Therefore it needs to be
33
21
possible to convert them to a meaningful string, and also for them to be
58
46
* create a new exception class for any class of error that can be
59
usefully distinguished. If no callers are likely to want to catch
60
one but not another, don't worry about them.
62
* the __str__ method should generate something useful; BzrError provides
63
a good default implementation
65
Exception strings should start with a capital letter and should not have a
47
usefully distinguished.
49
* the printable form of an exception is generated by the base class
52
Exception strings should start with a capital letter and not have a final
69
from warnings import warn
71
from bzrlib.patches import (PatchSyntax,
78
56
# based on Scott James Remnant's hct error classes
80
58
# TODO: is there any value in providing the .args field used by standard
88
66
# TODO: Convert all the other error classes here to BzrNewError, and eliminate
91
# TODO: The pattern (from hct) of using classes docstrings as message
92
# templates is cute but maybe not such a great idea - perhaps should have a
93
# separate static message_template.
96
70
class BzrError(StandardError):
100
71
def __str__(self):
101
72
# XXX: Should we show the exception class in
102
73
# exceptions that don't provide their own message?
162
128
class InvalidRevisionId(BzrNewError):
163
129
"""Invalid revision-id {%(revision_id)s} in %(branch)s"""
164
130
def __init__(self, revision_id, branch):
165
# branch can be any string or object with __str__ defined
166
131
BzrNewError.__init__(self)
167
132
self.revision_id = revision_id
168
133
self.branch = branch
171
136
class NoWorkingTree(BzrNewError):
172
"""No WorkingTree exists for %(base)s."""
137
"""No WorkingTree exists for %s(base)."""
174
139
def __init__(self, base):
175
140
BzrNewError.__init__(self)
179
144
class NotLocalUrl(BzrNewError):
180
"""%(url)s is not a local path."""
145
"""%s(url) is not a local path."""
182
147
def __init__(self, url):
183
148
BzrNewError.__init__(self)
187
class BzrCommandError(BzrNewError):
188
"""Error from user command"""
192
# Error from malformed user command; please avoid raising this as a
193
# generic exception not caused by user input.
152
class BzrCommandError(BzrError):
153
# Error from malformed user command
154
# This is being misused as a generic exception
155
# pleae subclass. RBC 20051030
195
157
# I think it's a waste of effort to differentiate between errors that
196
158
# are not intended to be caught anyway. UI code need not subclass
197
159
# BzrCommandError, and non-UI code should not throw a subclass of
198
160
# BzrCommandError. ADHB 20051211
199
def __init__(self, msg):
202
161
def __str__(self):
206
165
class BzrOptionError(BzrCommandError):
207
"""Error in command line options"""
166
"""Some missing or otherwise incorrect option was supplied."""
210
class StrictCommitFailed(BzrNewError):
211
"""Commit refused because there are unknown files in the tree"""
214
# XXX: Should be unified with TransportError; they seem to represent the
169
class StrictCommitFailed(Exception):
170
"""Commit refused because there are unknowns in the tree."""
216
173
class PathError(BzrNewError):
217
174
"""Generic path error: %(path)r%(extra)s)"""
219
175
def __init__(self, path, extra=None):
220
176
BzrNewError.__init__(self)
237
193
"""Directory not empty: %(path)r%(extra)s"""
240
class ResourceBusy(PathError):
241
"""Device or resource busy: %(path)r%(extra)s"""
244
196
class PermissionDenied(PathError):
245
197
"""Permission denied: %(path)r%(extra)s"""
248
class InvalidURL(PathError):
249
"""Invalid url supplied to transport: %(path)r%(extra)s"""
252
class InvalidURLJoin(PathError):
253
"""Invalid URL join request: %(args)s%(extra)s"""
255
def __init__(self, msg, base, args):
256
PathError.__init__(self, base, msg)
258
self.args.extend(args)
261
class UnsupportedProtocol(PathError):
262
"""Unsupported protocol for url "%(path)s"%(extra)s"""
264
def __init__(self, url, extra):
265
PathError.__init__(self, url, extra=extra)
268
200
class PathNotChild(BzrNewError):
269
201
"""Path %(path)r is not a child of path %(base)r%(extra)s"""
271
is_user_error = False
273
202
def __init__(self, path, base, extra=None):
274
203
BzrNewError.__init__(self)
283
class InvalidNormalization(PathError):
284
"""Path %(path)r is not unicode normalized"""
287
# TODO: This is given a URL; we try to unescape it but doing that from inside
288
# the exception object is a bit undesirable.
289
# TODO: Probably this behavior of should be a common superclass
290
class NotBranchError(PathError):
212
class NotBranchError(BzrNewError):
291
213
"""Not a branch: %(path)s"""
293
214
def __init__(self, path):
294
import bzrlib.urlutils as urlutils
295
self.path = urlutils.unescape_for_display(path, 'ascii')
298
class AlreadyBranchError(PathError):
299
"""Already a branch: %(path)s."""
302
class BranchExistsWithoutWorkingTree(PathError):
303
"""Directory contains a branch, but no working tree \
304
(use bzr checkout if you wish to build a working tree): %(path)s"""
215
BzrNewError.__init__(self)
307
219
class NoRepositoryPresent(BzrNewError):
308
"""No repository present: %(path)r"""
220
"""Not repository present: %(path)r"""
309
221
def __init__(self, bzrdir):
310
222
BzrNewError.__init__(self)
311
223
self.path = bzrdir.transport.clone('..').base
324
class UnsupportedFormatError(BzrNewError):
325
"""Unsupported branch format: %(format)s"""
328
class UnknownFormatError(BzrNewError):
329
"""Unknown branch format: %(format)r"""
236
class UnsupportedFormatError(BzrError):
237
"""Specified path is a bzr branch that we recognize but cannot read."""
239
return 'unsupported branch format: %s' % self.args[0]
242
class UnknownFormatError(BzrError):
243
"""Specified path is a bzr branch whose format we do not recognize."""
245
return 'unknown branch format: %s' % self.args[0]
332
248
class IncompatibleFormat(BzrNewError):
348
class PathsNotVersionedError(BzrNewError):
349
# used when reporting several paths are not versioned
350
"""Path(s) are not versioned: %(paths_as_string)s"""
352
def __init__(self, paths):
353
from bzrlib.osutils import quotefn
354
BzrNewError.__init__(self)
356
self.paths_as_string = ' '.join([quotefn(p) for p in paths])
359
class PathsDoNotExist(BzrNewError):
360
"""Path(s) do not exist: %(paths_as_string)s"""
362
# used when reporting that paths are neither versioned nor in the working
365
def __init__(self, paths):
367
from bzrlib.osutils import quotefn
368
BzrNewError.__init__(self)
370
self.paths_as_string = ' '.join([quotefn(p) for p in paths])
373
class BadFileKindError(BzrNewError):
374
"""Cannot operate on %(filename)s of unsupported kind %(kind)s"""
377
class ForbiddenControlFileError(BzrNewError):
378
"""Cannot operate on %(filename)s because it is a control file"""
264
class BadFileKindError(BzrError):
265
"""Specified file is of a kind that cannot be added.
267
(For example a symlink or device file.)"""
270
class ForbiddenFileError(BzrError):
271
"""Cannot operate on a file because it is a control file."""
381
274
class LockError(BzrNewError):
410
class OutSideTransaction(BzrNewError):
411
"""A transaction related operation was attempted after the transaction finished."""
414
class ObjectNotLocked(LockError):
415
"""%(obj)r is not locked"""
417
is_user_error = False
419
# this can indicate that any particular object is not locked; see also
420
# LockNotHeld which means that a particular *lock* object is not held by
421
# the caller -- perhaps they should be unified.
422
def __init__(self, obj):
303
class BranchNotLocked(LockError):
304
"""Branch %(branch)r is not locked"""
305
def __init__(self, branch):
306
# XXX: sometimes called with a LockableFiles instance not a Branch
426
310
class ReadOnlyObjectDirtiedError(ReadOnlyError):
478
368
self.format = format
482
371
class StrictCommitFailed(Exception):
483
372
"""Commit refused because there are unknowns in the tree."""
486
class NoSuchRevision(BzrNewError):
487
"""Branch %(branch)s has no revision %(revision)s"""
489
is_user_error = False
374
class NoSuchRevision(BzrError):
491
375
def __init__(self, branch, revision):
492
376
self.branch = branch
493
377
self.revision = revision
378
msg = "Branch %s has no revision %s" % (branch, revision)
379
BzrError.__init__(self, msg)
496
382
class HistoryMissing(BzrError):
501
387
% (branch, object_type, object_id))
504
class DivergedBranches(BzrNewError):
505
"These branches have diverged. Use the merge command to reconcile them."""
390
class DivergedBranches(BzrError):
509
391
def __init__(self, branch1, branch2):
392
BzrError.__init__(self, "These branches have diverged. Try merge.")
510
393
self.branch1 = branch1
511
394
self.branch2 = branch2
514
class UnrelatedBranches(BzrNewError):
515
"Branches have no common ancestor, and no merge base revision was specified."
520
class NoCommonAncestor(BzrNewError):
521
"Revisions have no common ancestor: %(revision_a)s %(revision_b)s"
397
class UnrelatedBranches(BzrCommandError):
399
msg = "Branches have no common ancestor, and no base revision"\
401
BzrCommandError.__init__(self, msg)
404
class NoCommonAncestor(BzrError):
523
405
def __init__(self, revision_a, revision_b):
524
self.revision_a = revision_a
525
self.revision_b = revision_b
406
msg = "Revisions have no common ancestor: %s %s." \
407
% (revision_a, revision_b)
408
BzrError.__init__(self, msg)
528
411
class NoCommonRoot(BzrError):
552
434
class AmbiguousBase(BzrError):
553
435
def __init__(self, bases):
554
warn("BzrError AmbiguousBase has been deprecated as of bzrlib 0.8.",
556
msg = "The correct base is unclear, because %s are all equally close" %\
436
msg = "The correct base is unclear, becase %s are all equally close" %\
558
438
BzrError.__init__(self, msg)
559
439
self.bases = bases
570
450
BzrError.__init__(self, "Store %s is not listable" % store)
574
453
class UnlistableBranch(BzrError):
575
454
def __init__(self, br):
576
455
BzrError.__init__(self, "Stores for branch %s are not listable" % br)
579
class BoundBranchOutOfDate(BzrNewError):
580
"""Bound branch %(branch)s is out of date with master branch %(master)s."""
581
def __init__(self, branch, master):
582
BzrNewError.__init__(self)
587
class CommitToDoubleBoundBranch(BzrNewError):
588
"""Cannot commit to branch %(branch)s. It is bound to %(master)s, which is bound to %(remote)s."""
589
def __init__(self, branch, master, remote):
590
BzrNewError.__init__(self)
596
class OverwriteBoundBranch(BzrNewError):
597
"""Cannot pull --overwrite to a branch which is bound %(branch)s"""
598
def __init__(self, branch):
599
BzrNewError.__init__(self)
603
class BoundBranchConnectionFailure(BzrNewError):
604
"""Unable to connect to target of bound branch %(branch)s => %(target)s: %(error)s"""
605
def __init__(self, branch, target, error):
606
BzrNewError.__init__(self)
612
458
class WeaveError(BzrNewError):
613
459
"""Error in processing weave: %(message)s"""
615
460
def __init__(self, message=None):
616
461
BzrNewError.__init__(self)
617
462
self.message = message
671
513
self.weave_b = weave_b
674
class VersionedFileError(BzrNewError):
675
"""Versioned file error."""
678
class RevisionNotPresent(VersionedFileError):
679
"""Revision {%(revision_id)s} not present in %(file_id)s."""
681
def __init__(self, revision_id, file_id):
682
VersionedFileError.__init__(self)
683
self.revision_id = revision_id
684
self.file_id = file_id
687
class RevisionAlreadyPresent(VersionedFileError):
688
"""Revision {%(revision_id)s} already present in %(file_id)s."""
690
def __init__(self, revision_id, file_id):
691
VersionedFileError.__init__(self)
692
self.revision_id = revision_id
693
self.file_id = file_id
696
class KnitError(BzrNewError):
700
class KnitHeaderError(KnitError):
701
"""Knit header error: %(badline)r unexpected"""
703
def __init__(self, badline):
704
KnitError.__init__(self)
705
self.badline = badline
708
class KnitCorrupt(KnitError):
709
"""Knit %(filename)s corrupt: %(how)s"""
711
def __init__(self, filename, how):
712
KnitError.__init__(self)
713
self.filename = filename
717
516
class NoSuchExportFormat(BzrNewError):
718
517
"""Export format %(format)r not supported"""
719
518
def __init__(self, format):
721
520
self.format = format
724
class TransportError(BzrNewError):
725
"""Transport error: %(msg)s %(orig_error)s"""
523
class TransportError(BzrError):
524
"""All errors thrown by Transport implementations should derive
727
527
def __init__(self, msg=None, orig_error=None):
728
528
if msg is None and orig_error is not None:
729
529
msg = str(orig_error)
730
if orig_error is None:
530
BzrError.__init__(self, msg)
735
532
self.orig_error = orig_error
736
BzrNewError.__init__(self)
739
535
# A set of semi-meaningful errors which can be thrown
740
536
class TransportNotPossible(TransportError):
741
"""Transport operation not possible: %(msg)s %(orig_error)%"""
537
"""This is for transports where a specific function is explicitly not
538
possible. Such as pushing files to an HTTP server.
744
543
class ConnectionError(TransportError):
745
"""Connection error: %(msg)s %(orig_error)s"""
544
"""A connection problem prevents file retrieval.
545
This does not indicate whether the file exists or not; it indicates that a
546
precondition for requesting the file was not met.
548
def __init__(self, msg=None, orig_error=None):
549
TransportError.__init__(self, msg=msg, orig_error=orig_error)
748
552
class ConnectionReset(TransportError):
749
"""Connection closed: %(msg)s %(orig_error)s"""
752
class InvalidRange(TransportError):
753
"""Invalid range access."""
755
def __init__(self, path, offset):
756
TransportError.__init__(self, ("Invalid range access in %s at %d"
760
class InvalidHttpResponse(TransportError):
761
"""Invalid http response for %(path)s: %(msg)s"""
763
def __init__(self, path, msg, orig_error=None):
765
TransportError.__init__(self, msg, orig_error=orig_error)
768
class InvalidHttpRange(InvalidHttpResponse):
769
"""Invalid http range "%(range)s" for %(path)s: %(msg)s"""
771
def __init__(self, path, range, msg):
773
InvalidHttpResponse.__init__(self, path, msg)
776
class InvalidHttpContentType(InvalidHttpResponse):
777
"""Invalid http Content-type "%(ctype)s" for %(path)s: %(msg)s"""
779
def __init__(self, path, ctype, msg):
781
InvalidHttpResponse.__init__(self, path, msg)
553
"""The connection has been closed."""
784
557
class ConflictsInTree(BzrError):
838
class NoBundleFound(BzrNewError):
839
"""No bundle was found in %(filename)s"""
840
def __init__(self, filename):
841
BzrNewError.__init__(self)
842
self.filename = filename
845
class BundleNotSupported(BzrNewError):
846
"""Unable to handle bundle version %(version)s: %(msg)s"""
847
def __init__(self, version, msg):
848
BzrNewError.__init__(self)
849
self.version = version
853
611
class MissingText(BzrNewError):
854
612
"""Branch %(base)s is missing revision %(text_revision)s of %(file_id)s"""
900
656
"""Parameter $(param)s is required but not present."""
903
class BzrBadParameterUnicode(BzrBadParameter):
904
"""Parameter %(param)s is unicode but only byte-strings are permitted."""
907
class BzrBadParameterContainsNewline(BzrBadParameter):
908
"""Parameter %(param)s contains a newline."""
911
659
class DependencyNotPresent(BzrNewError):
912
"""Unable to import library "%(library)s": %(error)s"""
660
"""Unable to import library: %(library)s, %(error)s"""
914
662
def __init__(self, library, error):
915
663
BzrNewError.__init__(self, library=library, error=error)
967
708
def __init__(self, tree):
968
709
BzrNewError.__init__(self)
972
class MergeModifiedFormatError(BzrNewError):
973
"""Error in merge modified format"""
976
class ConflictFormatError(BzrNewError):
977
"""Format error in conflict listings"""
980
class CorruptRepository(BzrNewError):
981
"""An error has been detected in the repository %(repo_path)s.
982
Please run bzr reconcile on this repository."""
984
def __init__(self, repo):
985
BzrNewError.__init__(self)
986
self.repo_path = repo.bzrdir.root_transport.base
989
class UpgradeRequired(BzrNewError):
990
"""To use this feature you must upgrade your branch at %(path)s."""
992
def __init__(self, path):
993
BzrNewError.__init__(self)
997
class LocalRequiresBoundBranch(BzrNewError):
998
"""Cannot perform local-only commits on unbound branches."""
1001
class MissingProgressBarFinish(BzrNewError):
1002
"""A nested progress bar was not 'finished' correctly."""
1005
class InvalidProgressBarType(BzrNewError):
1006
"""Environment variable BZR_PROGRESS_BAR='%(bar_type)s is not a supported type
1007
Select one of: %(valid_types)s"""
1009
def __init__(self, bar_type, valid_types):
1010
BzrNewError.__init__(self, bar_type=bar_type, valid_types=valid_types)
1013
class UnsupportedOperation(BzrNewError):
1014
"""The method %(mname)s is not supported on objects of type %(tname)s."""
1015
def __init__(self, method, method_self):
1016
self.method = method
1017
self.mname = method.__name__
1018
self.tname = type(method_self).__name__
1021
class BinaryFile(BzrNewError):
1022
"""File is binary but should be text."""
1025
class IllegalPath(BzrNewError):
1026
"""The path %(path)s is not permitted on this platform"""
1028
def __init__(self, path):
1029
BzrNewError.__init__(self)
1033
class TestamentMismatch(BzrNewError):
1034
"""Testament did not match expected value.
1035
For revision_id {%(revision_id)s}, expected {%(expected)s}, measured
1038
def __init__(self, revision_id, expected, measured):
1039
self.revision_id = revision_id
1040
self.expected = expected
1041
self.measured = measured
1044
class NotABundle(BzrNewError):
1045
"""Not a bzr revision-bundle: %(text)r"""
1047
def __init__(self, text):
1051
class BadBundle(Exception): pass
1054
class MalformedHeader(BadBundle): pass
1057
class MalformedPatches(BadBundle): pass
1060
class MalformedFooter(BadBundle): pass