~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/errors.py

  • Committer: Robert Collins
  • Date: 2006-06-16 15:59:24 UTC
  • mto: (1780.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 1781.
  • Revision ID: robertc@robertcollins.net-20060616155924-b8a6591d32f8ab20
New corner case from John Meinel, showing up the need to check the directory lexographically outside of a single tree's root. Fixed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#! /usr/bin/env python
2
 
# -*- coding: UTF-8 -*-
 
1
# Copyright (C) 2005, 2006 Canonical
3
2
 
4
3
# This program is free software; you can redistribute it and/or modify
5
4
# it under the terms of the GNU General Public License as published by
15
14
# along with this program; if not, write to the Free Software
16
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
16
 
18
 
 
19
 
__copyright__ = "Copyright (C) 2005 Canonical Ltd."
20
 
__author__ = "Martin Pool <mbp@canonical.com>"
21
 
 
22
 
 
23
 
######################################################################
24
 
# exceptions 
 
17
"""Exceptions for bzr, and reporting of them.
 
18
 
 
19
Exceptions are caught at a high level to report errors to the user, and
 
20
might also be caught inside the program.  Therefore it needs to be
 
21
possible to convert them to a meaningful string, and also for them to be
 
22
interrogated by the program.
 
23
 
 
24
Exceptions are defined such that the arguments given to the constructor
 
25
are stored in the object as properties of the same name.  When the
 
26
object is printed as a string, the doc string of the class is used as
 
27
a format string with the property dictionary available to it.
 
28
 
 
29
This means that exceptions can used like this:
 
30
 
 
31
>>> import sys
 
32
>>> try:
 
33
...   raise NotBranchError(path='/foo/bar')
 
34
... except:
 
35
...   print sys.exc_type
 
36
...   print sys.exc_value
 
37
...   path = getattr(sys.exc_value, 'path', None)
 
38
...   if path is not None:
 
39
...     print path
 
40
bzrlib.errors.NotBranchError
 
41
Not a branch: /foo/bar
 
42
/foo/bar
 
43
 
 
44
Therefore:
 
45
 
 
46
 * create a new exception class for any class of error that can be
 
47
   usefully distinguished.
 
48
 
 
49
 * the printable form of an exception is generated by the base class
 
50
   __str__ method
 
51
 
 
52
Exception strings should start with a capital letter and not have a final
 
53
fullstop.
 
54
"""
 
55
 
 
56
from warnings import warn
 
57
 
 
58
from bzrlib.patches import (PatchSyntax, 
 
59
                            PatchConflict, 
 
60
                            MalformedPatchHeader,
 
61
                            MalformedHunkHeader,
 
62
                            MalformedLine,)
 
63
 
 
64
 
 
65
# based on Scott James Remnant's hct error classes
 
66
 
 
67
# TODO: is there any value in providing the .args field used by standard
 
68
# python exceptions?   A list of values with no names seems less useful 
 
69
# to me.
 
70
 
 
71
# TODO: Perhaps convert the exception to a string at the moment it's 
 
72
# constructed to make sure it will succeed.  But that says nothing about
 
73
# exceptions that are never raised.
 
74
 
 
75
# TODO: Convert all the other error classes here to BzrNewError, and eliminate
 
76
# the old one.
 
77
 
 
78
# TODO: The pattern (from hct) of using classes docstrings as message
 
79
# templates is cute but maybe not such a great idea - perhaps should have a
 
80
# separate static message_template.
 
81
 
 
82
 
25
83
class BzrError(StandardError):
26
 
    pass
27
 
 
28
 
class BzrCheckError(BzrError):
29
 
    pass
 
84
    def __str__(self):
 
85
        # XXX: Should we show the exception class in 
 
86
        # exceptions that don't provide their own message?  
 
87
        # maybe it should be done at a higher level
 
88
        ## n = self.__class__.__name__ + ': '
 
89
        n = ''
 
90
        if len(self.args) == 1:
 
91
            return str(self.args[0])
 
92
        elif len(self.args) == 2:
 
93
            # further explanation or suggestions
 
94
            try:
 
95
                return n + '\n  '.join([self.args[0]] + self.args[1])
 
96
            except TypeError:
 
97
                return n + "%r" % self
 
98
        else:
 
99
            return n + `self.args`
 
100
 
 
101
 
 
102
class BzrNewError(BzrError):
 
103
    """bzr error"""
 
104
    # base classes should override the docstring with their human-
 
105
    # readable explanation
 
106
 
 
107
    def __init__(self, **kwds):
 
108
        for key, value in kwds.items():
 
109
            setattr(self, key, value)
 
110
 
 
111
    def __str__(self):
 
112
        try:
 
113
            return self.__doc__ % self.__dict__
 
114
        except (NameError, ValueError, KeyError), e:
 
115
            return 'Unprintable exception %s: %s' \
 
116
                % (self.__class__.__name__, str(e))
 
117
 
 
118
 
 
119
class BzrCheckError(BzrNewError):
 
120
    """Internal check failed: %(message)s"""
 
121
 
 
122
    def __init__(self, message):
 
123
        BzrNewError.__init__(self)
 
124
        self.message = message
 
125
 
 
126
 
 
127
class InvalidEntryName(BzrNewError):
 
128
    """Invalid entry name: %(name)s"""
 
129
    def __init__(self, name):
 
130
        BzrNewError.__init__(self)
 
131
        self.name = name
 
132
 
 
133
 
 
134
class InvalidRevisionNumber(BzrNewError):
 
135
    """Invalid revision number %(revno)d"""
 
136
    def __init__(self, revno):
 
137
        BzrNewError.__init__(self)
 
138
        self.revno = revno
 
139
 
 
140
 
 
141
class InvalidRevisionId(BzrNewError):
 
142
    """Invalid revision-id {%(revision_id)s} in %(branch)s"""
 
143
    def __init__(self, revision_id, branch):
 
144
        # branch can be any string or object with __str__ defined
 
145
        BzrNewError.__init__(self)
 
146
        self.revision_id = revision_id
 
147
        self.branch = branch
 
148
 
 
149
 
 
150
class NoWorkingTree(BzrNewError):
 
151
    """No WorkingTree exists for %(base)s."""
 
152
    
 
153
    def __init__(self, base):
 
154
        BzrNewError.__init__(self)
 
155
        self.base = base
 
156
 
 
157
 
 
158
class NotLocalUrl(BzrNewError):
 
159
    """%(url)s is not a local path."""
 
160
    
 
161
    def __init__(self, url):
 
162
        BzrNewError.__init__(self)
 
163
        self.url = url
30
164
 
31
165
 
32
166
class BzrCommandError(BzrError):
33
167
    # Error from malformed user command
34
 
    pass
35
 
 
36
 
 
37
 
class NotBranchError(BzrError):
38
 
    """Specified path is not in a branch"""
39
 
    pass
 
168
    # This is being misused as a generic exception
 
169
    # please subclass. RBC 20051030
 
170
    #
 
171
    # I think it's a waste of effort to differentiate between errors that
 
172
    # are not intended to be caught anyway.  UI code need not subclass
 
173
    # BzrCommandError, and non-UI code should not throw a subclass of
 
174
    # BzrCommandError.  ADHB 20051211
 
175
    def __str__(self):
 
176
        return self.args[0]
 
177
 
 
178
 
 
179
class BzrOptionError(BzrCommandError):
 
180
    """Some missing or otherwise incorrect option was supplied."""
 
181
 
 
182
    
 
183
class StrictCommitFailed(Exception):
 
184
    """Commit refused because there are unknowns in the tree."""
 
185
 
 
186
 
 
187
# XXX: Should be unified with TransportError; they seem to represent the
 
188
# same thing
 
189
class PathError(BzrNewError):
 
190
    """Generic path error: %(path)r%(extra)s)"""
 
191
 
 
192
    def __init__(self, path, extra=None):
 
193
        BzrNewError.__init__(self)
 
194
        self.path = path
 
195
        if extra:
 
196
            self.extra = ': ' + str(extra)
 
197
        else:
 
198
            self.extra = ''
 
199
 
 
200
 
 
201
class NoSuchFile(PathError):
 
202
    """No such file: %(path)r%(extra)s"""
 
203
 
 
204
 
 
205
class FileExists(PathError):
 
206
    """File exists: %(path)r%(extra)s"""
 
207
 
 
208
 
 
209
class DirectoryNotEmpty(PathError):
 
210
    """Directory not empty: %(path)r%(extra)s"""
 
211
 
 
212
 
 
213
class ResourceBusy(PathError):
 
214
    """Device or resource busy: %(path)r%(extra)s"""
 
215
 
 
216
 
 
217
class PermissionDenied(PathError):
 
218
    """Permission denied: %(path)r%(extra)s"""
 
219
 
 
220
 
 
221
class InvalidURL(PathError):
 
222
    """Invalid url supplied to transport: %(path)r%(extra)s"""
 
223
 
 
224
 
 
225
class InvalidURLJoin(PathError):
 
226
    """Invalid URL join request: %(args)s%(extra)s"""
 
227
 
 
228
    def __init__(self, msg, base, args):
 
229
        PathError.__init__(self, base, msg)
 
230
        self.args = [base]
 
231
        self.args.extend(args)
 
232
 
 
233
 
 
234
class PathNotChild(BzrNewError):
 
235
    """Path %(path)r is not a child of path %(base)r%(extra)s"""
 
236
    def __init__(self, path, base, extra=None):
 
237
        BzrNewError.__init__(self)
 
238
        self.path = path
 
239
        self.base = base
 
240
        if extra:
 
241
            self.extra = ': ' + str(extra)
 
242
        else:
 
243
            self.extra = ''
 
244
 
 
245
 
 
246
# TODO: This is given a URL; we try to unescape it but doing that from inside
 
247
# the exception object is a bit undesirable.
 
248
# TODO: Probably this behavior of should be a common superclass 
 
249
class NotBranchError(PathError):
 
250
    """Not a branch: %(path)s"""
 
251
 
 
252
    def __init__(self, path):
 
253
       import bzrlib.urlutils as urlutils
 
254
       self.path = urlutils.unescape_for_display(path, 'ascii')
 
255
 
 
256
 
 
257
class AlreadyBranchError(PathError):
 
258
    """Already a branch: %(path)s."""
 
259
 
 
260
 
 
261
class BranchExistsWithoutWorkingTree(PathError):
 
262
    """Directory contains a branch, but no working tree \
 
263
(use bzr checkout if you wish to build a working tree): %(path)s"""
 
264
 
 
265
 
 
266
class NoRepositoryPresent(BzrNewError):
 
267
    """No repository present: %(path)r"""
 
268
    def __init__(self, bzrdir):
 
269
        BzrNewError.__init__(self)
 
270
        self.path = bzrdir.transport.clone('..').base
 
271
 
 
272
 
 
273
class FileInWrongBranch(BzrNewError):
 
274
    """File %(path)s in not in branch %(branch_base)s."""
 
275
 
 
276
    def __init__(self, branch, path):
 
277
        BzrNewError.__init__(self)
 
278
        self.branch = branch
 
279
        self.branch_base = branch.base
 
280
        self.path = path
 
281
 
 
282
 
 
283
class UnsupportedFormatError(BzrError):
 
284
    """Specified path is a bzr branch that we recognize but cannot read."""
 
285
    def __str__(self):
 
286
        return 'unsupported branch format: %s' % self.args[0]
 
287
 
 
288
 
 
289
class UnknownFormatError(BzrError):
 
290
    """Specified path is a bzr branch whose format we do not recognize."""
 
291
    def __str__(self):
 
292
        return 'unknown branch format: %s' % self.args[0]
 
293
 
 
294
 
 
295
class IncompatibleFormat(BzrNewError):
 
296
    """Format %(format)s is not compatible with .bzr version %(bzrdir)s."""
 
297
 
 
298
    def __init__(self, format, bzrdir_format):
 
299
        BzrNewError.__init__(self)
 
300
        self.format = format
 
301
        self.bzrdir = bzrdir_format
 
302
 
 
303
 
 
304
class NotVersionedError(BzrNewError):
 
305
    """%(path)s is not versioned"""
 
306
    def __init__(self, path):
 
307
        BzrNewError.__init__(self)
 
308
        self.path = path
 
309
 
 
310
 
 
311
class PathsNotVersionedError(BzrNewError):
 
312
    # used when reporting several paths are not versioned
 
313
    """Path(s) are not versioned: %(paths_as_string)s"""
 
314
 
 
315
    def __init__(self, paths):
 
316
        from bzrlib.osutils import quotefn
 
317
        BzrNewError.__init__(self)
 
318
        self.paths = paths
 
319
        self.paths_as_string = ' '.join([quotefn(p) for p in paths])
 
320
 
 
321
 
 
322
class PathsDoNotExist(BzrNewError):
 
323
    """Path(s) do not exist: %(paths_as_string)s"""
 
324
 
 
325
    # used when reporting that paths are neither versioned nor in the working
 
326
    # tree
 
327
 
 
328
    def __init__(self, paths):
 
329
        # circular import
 
330
        from bzrlib.osutils import quotefn
 
331
        BzrNewError.__init__(self)
 
332
        self.paths = paths
 
333
        self.paths_as_string = ' '.join([quotefn(p) for p in paths])
40
334
 
41
335
 
42
336
class BadFileKindError(BzrError):
43
337
    """Specified file is of a kind that cannot be added.
44
338
 
45
339
    (For example a symlink or device file.)"""
46
 
    pass
47
340
 
48
341
 
49
342
class ForbiddenFileError(BzrError):
50
343
    """Cannot operate on a file because it is a control file."""
51
 
    pass
52
 
 
53
 
 
54
 
class LockError(Exception):
55
 
    """All exceptions from the lock/unlock functions should be from
56
 
    this exception class.  They will be translated as necessary. The
57
 
    original exception is available as e.original_error
58
 
    """
59
 
    def __init__(self, e=None):
60
 
        self.original_error = e
61
 
        if e:
62
 
            Exception.__init__(self, e)
63
 
        else:
64
 
            Exception.__init__(self)
65
 
 
66
 
 
67
 
 
68
 
def bailout(msg, explanation=[]):
69
 
    ex = BzrError(msg, explanation)
70
 
    import trace
71
 
    trace._tracefile.write('* raising %s\n' % ex)
72
 
    raise ex
73
 
 
 
344
 
 
345
 
 
346
class LockError(BzrNewError):
 
347
    """Lock error: %(message)s"""
 
348
    # All exceptions from the lock/unlock functions should be from
 
349
    # this exception class.  They will be translated as necessary. The
 
350
    # original exception is available as e.original_error
 
351
    #
 
352
    # New code should prefer to raise specific subclasses
 
353
    def __init__(self, message):
 
354
        self.message = message
 
355
 
 
356
 
 
357
class CommitNotPossible(LockError):
 
358
    """A commit was attempted but we do not have a write lock open."""
 
359
    def __init__(self):
 
360
        pass
 
361
 
 
362
 
 
363
class AlreadyCommitted(LockError):
 
364
    """A rollback was requested, but is not able to be accomplished."""
 
365
    def __init__(self):
 
366
        pass
 
367
 
 
368
 
 
369
class ReadOnlyError(LockError):
 
370
    """A write attempt was made in a read only transaction on %(obj)s"""
 
371
    def __init__(self, obj):
 
372
        self.obj = obj
 
373
 
 
374
 
 
375
class OutSideTransaction(BzrNewError):
 
376
    """A transaction related operation was attempted after the transaction finished."""
 
377
 
 
378
 
 
379
class ObjectNotLocked(LockError):
 
380
    """%(obj)r is not locked"""
 
381
    # this can indicate that any particular object is not locked; see also
 
382
    # LockNotHeld which means that a particular *lock* object is not held by
 
383
    # the caller -- perhaps they should be unified.
 
384
    def __init__(self, obj):
 
385
        self.obj = obj
 
386
 
 
387
 
 
388
class ReadOnlyObjectDirtiedError(ReadOnlyError):
 
389
    """Cannot change object %(obj)r in read only transaction"""
 
390
    def __init__(self, obj):
 
391
        self.obj = obj
 
392
 
 
393
 
 
394
class UnlockableTransport(LockError):
 
395
    """Cannot lock: transport is read only: %(transport)s"""
 
396
    def __init__(self, transport):
 
397
        self.transport = transport
 
398
 
 
399
 
 
400
class LockContention(LockError):
 
401
    """Could not acquire lock %(lock)s"""
 
402
    # TODO: show full url for lock, combining the transport and relative bits?
 
403
    def __init__(self, lock):
 
404
        self.lock = lock
 
405
 
 
406
 
 
407
class LockBroken(LockError):
 
408
    """Lock was broken while still open: %(lock)s - check storage consistency!"""
 
409
    def __init__(self, lock):
 
410
        self.lock = lock
 
411
 
 
412
 
 
413
class LockBreakMismatch(LockError):
 
414
    """Lock was released and re-acquired before being broken: %(lock)s: held by %(holder)r, wanted to break %(target)r"""
 
415
    def __init__(self, lock, holder, target):
 
416
        self.lock = lock
 
417
        self.holder = holder
 
418
        self.target = target
 
419
 
 
420
 
 
421
class LockNotHeld(LockError):
 
422
    """Lock not held: %(lock)s"""
 
423
    def __init__(self, lock):
 
424
        self.lock = lock
 
425
 
 
426
 
 
427
class PointlessCommit(BzrNewError):
 
428
    """No changes to commit"""
 
429
 
 
430
 
 
431
class UpgradeReadonly(BzrNewError):
 
432
    """Upgrade URL cannot work with readonly URL's."""
 
433
 
 
434
 
 
435
class UpToDateFormat(BzrNewError):
 
436
    """The branch format %(format)s is already at the most recent format."""
 
437
 
 
438
    def __init__(self, format):
 
439
        BzrNewError.__init__(self)
 
440
        self.format = format
 
441
 
 
442
 
 
443
 
 
444
class StrictCommitFailed(Exception):
 
445
    """Commit refused because there are unknowns in the tree."""
 
446
 
 
447
 
 
448
class NoSuchRevision(BzrError):
 
449
    def __init__(self, branch, revision):
 
450
        self.branch = branch
 
451
        self.revision = revision
 
452
        msg = "Branch %s has no revision %s" % (branch, revision)
 
453
        BzrError.__init__(self, msg)
 
454
 
 
455
 
 
456
class HistoryMissing(BzrError):
 
457
    def __init__(self, branch, object_type, object_id):
 
458
        self.branch = branch
 
459
        BzrError.__init__(self,
 
460
                          '%s is missing %s {%s}'
 
461
                          % (branch, object_type, object_id))
 
462
 
 
463
 
 
464
class DivergedBranches(BzrError):
 
465
 
 
466
    def __init__(self, branch1, branch2):
 
467
        BzrError.__init__(self, "These branches have diverged.  Try merge.")
 
468
        self.branch1 = branch1
 
469
        self.branch2 = branch2
 
470
 
 
471
 
 
472
class UnrelatedBranches(BzrCommandError):
 
473
    def __init__(self):
 
474
        msg = "Branches have no common ancestor, and no base revision"\
 
475
            " specified."
 
476
        BzrCommandError.__init__(self, msg)
 
477
 
 
478
 
 
479
class NoCommonAncestor(BzrError):
 
480
    def __init__(self, revision_a, revision_b):
 
481
        msg = "Revisions have no common ancestor: %s %s." \
 
482
            % (revision_a, revision_b) 
 
483
        BzrError.__init__(self, msg)
 
484
 
 
485
 
 
486
class NoCommonRoot(BzrError):
 
487
    def __init__(self, revision_a, revision_b):
 
488
        msg = "Revisions are not derived from the same root: %s %s." \
 
489
            % (revision_a, revision_b) 
 
490
        BzrError.__init__(self, msg)
 
491
 
 
492
 
 
493
 
 
494
class NotAncestor(BzrError):
 
495
    def __init__(self, rev_id, not_ancestor_id):
 
496
        msg = "Revision %s is not an ancestor of %s" % (not_ancestor_id, 
 
497
                                                        rev_id)
 
498
        BzrError.__init__(self, msg)
 
499
        self.rev_id = rev_id
 
500
        self.not_ancestor_id = not_ancestor_id
 
501
 
 
502
 
 
503
class InstallFailed(BzrError):
 
504
    def __init__(self, revisions):
 
505
        msg = "Could not install revisions:\n%s" % " ,".join(revisions)
 
506
        BzrError.__init__(self, msg)
 
507
        self.revisions = revisions
 
508
 
 
509
 
 
510
class AmbiguousBase(BzrError):
 
511
    def __init__(self, bases):
 
512
        warn("BzrError AmbiguousBase has been deprecated as of bzrlib 0.8.",
 
513
                DeprecationWarning)
 
514
        msg = "The correct base is unclear, because %s are all equally close" %\
 
515
            ", ".join(bases)
 
516
        BzrError.__init__(self, msg)
 
517
        self.bases = bases
 
518
 
 
519
 
 
520
class NoCommits(BzrError):
 
521
    def __init__(self, branch):
 
522
        msg = "Branch %s has no commits." % branch
 
523
        BzrError.__init__(self, msg)
 
524
 
 
525
 
 
526
class UnlistableStore(BzrError):
 
527
    def __init__(self, store):
 
528
        BzrError.__init__(self, "Store %s is not listable" % store)
 
529
 
 
530
 
 
531
 
 
532
class UnlistableBranch(BzrError):
 
533
    def __init__(self, br):
 
534
        BzrError.__init__(self, "Stores for branch %s are not listable" % br)
 
535
 
 
536
 
 
537
class BoundBranchOutOfDate(BzrNewError):
 
538
    """Bound branch %(branch)s is out of date with master branch %(master)s."""
 
539
    def __init__(self, branch, master):
 
540
        BzrNewError.__init__(self)
 
541
        self.branch = branch
 
542
        self.master = master
 
543
 
 
544
        
 
545
class CommitToDoubleBoundBranch(BzrNewError):
 
546
    """Cannot commit to branch %(branch)s. It is bound to %(master)s, which is bound to %(remote)s."""
 
547
    def __init__(self, branch, master, remote):
 
548
        BzrNewError.__init__(self)
 
549
        self.branch = branch
 
550
        self.master = master
 
551
        self.remote = remote
 
552
 
 
553
 
 
554
class OverwriteBoundBranch(BzrNewError):
 
555
    """Cannot pull --overwrite to a branch which is bound %(branch)s"""
 
556
    def __init__(self, branch):
 
557
        BzrNewError.__init__(self)
 
558
        self.branch = branch
 
559
 
 
560
 
 
561
class BoundBranchConnectionFailure(BzrNewError):
 
562
    """Unable to connect to target of bound branch %(branch)s => %(target)s: %(error)s"""
 
563
    def __init__(self, branch, target, error):
 
564
        BzrNewError.__init__(self)
 
565
        self.branch = branch
 
566
        self.target = target
 
567
        self.error = error
 
568
 
 
569
 
 
570
class WeaveError(BzrNewError):
 
571
    """Error in processing weave: %(message)s"""
 
572
 
 
573
    def __init__(self, message=None):
 
574
        BzrNewError.__init__(self)
 
575
        self.message = message
 
576
 
 
577
 
 
578
class WeaveRevisionAlreadyPresent(WeaveError):
 
579
    """Revision {%(revision_id)s} already present in %(weave)s"""
 
580
    def __init__(self, revision_id, weave):
 
581
 
 
582
        WeaveError.__init__(self)
 
583
        self.revision_id = revision_id
 
584
        self.weave = weave
 
585
 
 
586
 
 
587
class WeaveRevisionNotPresent(WeaveError):
 
588
    """Revision {%(revision_id)s} not present in %(weave)s"""
 
589
 
 
590
    def __init__(self, revision_id, weave):
 
591
        WeaveError.__init__(self)
 
592
        self.revision_id = revision_id
 
593
        self.weave = weave
 
594
 
 
595
 
 
596
class WeaveFormatError(WeaveError):
 
597
    """Weave invariant violated: %(what)s"""
 
598
 
 
599
    def __init__(self, what):
 
600
        WeaveError.__init__(self)
 
601
        self.what = what
 
602
 
 
603
 
 
604
class WeaveParentMismatch(WeaveError):
 
605
    """Parents are mismatched between two revisions."""
 
606
    
 
607
 
 
608
class WeaveInvalidChecksum(WeaveError):
 
609
    """Text did not match it's checksum: %(message)s"""
 
610
 
 
611
 
 
612
class WeaveTextDiffers(WeaveError):
 
613
    """Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
 
614
 
 
615
    def __init__(self, revision_id, weave_a, weave_b):
 
616
        WeaveError.__init__(self)
 
617
        self.revision_id = revision_id
 
618
        self.weave_a = weave_a
 
619
        self.weave_b = weave_b
 
620
 
 
621
 
 
622
class WeaveTextDiffers(WeaveError):
 
623
    """Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
 
624
 
 
625
    def __init__(self, revision_id, weave_a, weave_b):
 
626
        WeaveError.__init__(self)
 
627
        self.revision_id = revision_id
 
628
        self.weave_a = weave_a
 
629
        self.weave_b = weave_b
 
630
 
 
631
 
 
632
class VersionedFileError(BzrNewError):
 
633
    """Versioned file error."""
 
634
 
 
635
 
 
636
class RevisionNotPresent(VersionedFileError):
 
637
    """Revision {%(revision_id)s} not present in %(file_id)s."""
 
638
 
 
639
    def __init__(self, revision_id, file_id):
 
640
        VersionedFileError.__init__(self)
 
641
        self.revision_id = revision_id
 
642
        self.file_id = file_id
 
643
 
 
644
 
 
645
class RevisionAlreadyPresent(VersionedFileError):
 
646
    """Revision {%(revision_id)s} already present in %(file_id)s."""
 
647
 
 
648
    def __init__(self, revision_id, file_id):
 
649
        VersionedFileError.__init__(self)
 
650
        self.revision_id = revision_id
 
651
        self.file_id = file_id
 
652
 
 
653
 
 
654
class KnitError(BzrNewError):
 
655
    """Knit error"""
 
656
 
 
657
 
 
658
class KnitHeaderError(KnitError):
 
659
    """Knit header error: %(badline)r unexpected"""
 
660
 
 
661
    def __init__(self, badline):
 
662
        KnitError.__init__(self)
 
663
        self.badline = badline
 
664
 
 
665
 
 
666
class KnitCorrupt(KnitError):
 
667
    """Knit %(filename)s corrupt: %(how)s"""
 
668
 
 
669
    def __init__(self, filename, how):
 
670
        KnitError.__init__(self)
 
671
        self.filename = filename
 
672
        self.how = how
 
673
 
 
674
 
 
675
class NoSuchExportFormat(BzrNewError):
 
676
    """Export format %(format)r not supported"""
 
677
    def __init__(self, format):
 
678
        BzrNewError.__init__(self)
 
679
        self.format = format
 
680
 
 
681
 
 
682
class TransportError(BzrError):
 
683
    """All errors thrown by Transport implementations should derive
 
684
    from this class.
 
685
    """
 
686
    def __init__(self, msg=None, orig_error=None):
 
687
        if msg is None and orig_error is not None:
 
688
            msg = str(orig_error)
 
689
        BzrError.__init__(self, msg)
 
690
        self.msg = msg
 
691
        self.orig_error = orig_error
 
692
 
 
693
 
 
694
# A set of semi-meaningful errors which can be thrown
 
695
class TransportNotPossible(TransportError):
 
696
    """This is for transports where a specific function is explicitly not
 
697
    possible. Such as pushing files to an HTTP server.
 
698
    """
 
699
    pass
 
700
 
 
701
 
 
702
class ConnectionError(TransportError):
 
703
    """A connection problem prevents file retrieval.
 
704
    This does not indicate whether the file exists or not; it indicates that a
 
705
    precondition for requesting the file was not met.
 
706
    """
 
707
    def __init__(self, msg=None, orig_error=None):
 
708
        TransportError.__init__(self, msg=msg, orig_error=orig_error)
 
709
 
 
710
 
 
711
class ConnectionReset(TransportError):
 
712
    """The connection has been closed."""
 
713
    pass
 
714
 
 
715
 
 
716
class ConflictsInTree(BzrError):
 
717
    def __init__(self):
 
718
        BzrError.__init__(self, "Working tree has conflicts.")
 
719
 
 
720
 
 
721
class ParseConfigError(BzrError):
 
722
    def __init__(self, errors, filename):
 
723
        if filename is None:
 
724
            filename = ""
 
725
        message = "Error(s) parsing config file %s:\n%s" % \
 
726
            (filename, ('\n'.join(e.message for e in errors)))
 
727
        BzrError.__init__(self, message)
 
728
 
 
729
 
 
730
class SigningFailed(BzrError):
 
731
    def __init__(self, command_line):
 
732
        BzrError.__init__(self, "Failed to gpg sign data with command '%s'"
 
733
                               % command_line)
 
734
 
 
735
 
 
736
class WorkingTreeNotRevision(BzrError):
 
737
    def __init__(self, tree):
 
738
        BzrError.__init__(self, "The working tree for %s has changed since"
 
739
                          " last commit, but weave merge requires that it be"
 
740
                          " unchanged." % tree.basedir)
 
741
 
 
742
 
 
743
class CantReprocessAndShowBase(BzrNewError):
 
744
    """Can't reprocess and show base.
 
745
Reprocessing obscures relationship of conflicting lines to base."""
 
746
 
 
747
 
 
748
class GraphCycleError(BzrNewError):
 
749
    """Cycle in graph %(graph)r"""
 
750
    def __init__(self, graph):
 
751
        BzrNewError.__init__(self)
 
752
        self.graph = graph
 
753
 
 
754
 
 
755
class NotConflicted(BzrNewError):
 
756
    """File %(filename)s is not conflicted."""
 
757
 
 
758
    def __init__(self, filename):
 
759
        BzrNewError.__init__(self)
 
760
        self.filename = filename
 
761
 
 
762
 
 
763
class MustUseDecorated(Exception):
 
764
    """A decorating function has requested its original command be used.
 
765
    
 
766
    This should never escape bzr, so does not need to be printable.
 
767
    """
 
768
 
 
769
 
 
770
class NoBundleFound(BzrNewError):
 
771
    """No bundle was found in %(filename)s"""
 
772
    def __init__(self, filename):
 
773
        BzrNewError.__init__(self)
 
774
        self.filename = filename
 
775
 
 
776
 
 
777
class BundleNotSupported(BzrNewError):
 
778
    """Unable to handle bundle version %(version)s: %(msg)s"""
 
779
    def __init__(self, version, msg):
 
780
        BzrNewError.__init__(self)
 
781
        self.version = version
 
782
        self.msg = msg
 
783
 
 
784
 
 
785
class MissingText(BzrNewError):
 
786
    """Branch %(base)s is missing revision %(text_revision)s of %(file_id)s"""
 
787
 
 
788
    def __init__(self, branch, text_revision, file_id):
 
789
        BzrNewError.__init__(self)
 
790
        self.branch = branch
 
791
        self.base = branch.base
 
792
        self.text_revision = text_revision
 
793
        self.file_id = file_id
 
794
 
 
795
 
 
796
class DuplicateKey(BzrNewError):
 
797
    """Key %(key)s is already present in map"""
 
798
 
 
799
 
 
800
class MalformedTransform(BzrNewError):
 
801
    """Tree transform is malformed %(conflicts)r"""
 
802
 
 
803
 
 
804
class BzrBadParameter(BzrNewError):
 
805
    """A bad parameter : %(param)s is not usable.
 
806
    
 
807
    This exception should never be thrown, but it is a base class for all
 
808
    parameter-to-function errors.
 
809
    """
 
810
    def __init__(self, param):
 
811
        BzrNewError.__init__(self)
 
812
        self.param = param
 
813
 
 
814
 
 
815
class BzrBadParameterNotUnicode(BzrBadParameter):
 
816
    """Parameter %(param)s is neither unicode nor utf8."""
 
817
 
 
818
 
 
819
class ReusingTransform(BzrNewError):
 
820
    """Attempt to reuse a transform that has already been applied."""
 
821
 
 
822
 
 
823
class CantMoveRoot(BzrNewError):
 
824
    """Moving the root directory is not supported at this time"""
 
825
 
 
826
 
 
827
class BzrBadParameterNotString(BzrBadParameter):
 
828
    """Parameter %(param)s is not a string or unicode string."""
 
829
 
 
830
 
 
831
class BzrBadParameterMissing(BzrBadParameter):
 
832
    """Parameter $(param)s is required but not present."""
 
833
 
 
834
 
 
835
class BzrBadParameterUnicode(BzrBadParameter):
 
836
    """Parameter %(param)s is unicode but only byte-strings are permitted."""
 
837
 
 
838
 
 
839
class BzrBadParameterContainsNewline(BzrBadParameter):
 
840
    """Parameter %(param)s contains a newline."""
 
841
 
 
842
 
 
843
class DependencyNotPresent(BzrNewError):
 
844
    """Unable to import library "%(library)s": %(error)s"""
 
845
 
 
846
    def __init__(self, library, error):
 
847
        BzrNewError.__init__(self, library=library, error=error)
 
848
 
 
849
 
 
850
class ParamikoNotPresent(DependencyNotPresent):
 
851
    """Unable to import paramiko (required for sftp support): %(error)s"""
 
852
 
 
853
    def __init__(self, error):
 
854
        DependencyNotPresent.__init__(self, 'paramiko', error)
 
855
 
 
856
 
 
857
class UninitializableFormat(BzrNewError):
 
858
    """Format %(format)s cannot be initialised by this version of bzr."""
 
859
 
 
860
    def __init__(self, format):
 
861
        BzrNewError.__init__(self)
 
862
        self.format = format
 
863
 
 
864
 
 
865
class NoDiff3(BzrNewError):
 
866
    """Diff3 is not installed on this machine."""
 
867
 
 
868
 
 
869
class ExistingLimbo(BzrNewError):
 
870
    """This tree contains left-over files from a failed operation.
 
871
    Please examine %(limbo_dir)s to see if it contains any files you wish to
 
872
    keep, and delete it when you are done.
 
873
    """
 
874
    def __init__(self, limbo_dir):
 
875
       BzrNewError.__init__(self)
 
876
       self.limbo_dir = limbo_dir
 
877
 
 
878
 
 
879
class ImmortalLimbo(BzrNewError):
 
880
    """Unable to delete transform temporary directory $(limbo_dir)s.
 
881
    Please examine %(limbo_dir)s to see if it contains any files you wish to
 
882
    keep, and delete it when you are done.
 
883
    """
 
884
    def __init__(self, limbo_dir):
 
885
       BzrNewError.__init__(self)
 
886
       self.limbo_dir = limbo_dir
 
887
 
 
888
 
 
889
class OutOfDateTree(BzrNewError):
 
890
    """Working tree is out of date, please run 'bzr update'."""
 
891
 
 
892
    def __init__(self, tree):
 
893
        BzrNewError.__init__(self)
 
894
        self.tree = tree
 
895
 
 
896
 
 
897
class MergeModifiedFormatError(BzrNewError):
 
898
    """Error in merge modified format"""
 
899
 
 
900
 
 
901
class ConflictFormatError(BzrNewError):
 
902
    """Format error in conflict listings"""
 
903
 
 
904
 
 
905
class CorruptRepository(BzrNewError):
 
906
    """An error has been detected in the repository %(repo_path)s.
 
907
Please run bzr reconcile on this repository."""
 
908
 
 
909
    def __init__(self, repo):
 
910
        BzrNewError.__init__(self)
 
911
        self.repo_path = repo.bzrdir.root_transport.base
 
912
 
 
913
 
 
914
class UpgradeRequired(BzrNewError):
 
915
    """To use this feature you must upgrade your branch at %(path)s."""
 
916
 
 
917
    def __init__(self, path):
 
918
        BzrNewError.__init__(self)
 
919
        self.path = path
 
920
 
 
921
 
 
922
class LocalRequiresBoundBranch(BzrNewError):
 
923
    """Cannot perform local-only commits on unbound branches."""
 
924
 
 
925
 
 
926
class MissingProgressBarFinish(BzrNewError):
 
927
    """A nested progress bar was not 'finished' correctly."""
 
928
 
 
929
 
 
930
class UnsupportedOperation(BzrNewError):
 
931
    """The method %(mname)s is not supported on objects of type %(tname)s."""
 
932
    def __init__(self, method, method_self):
 
933
        self.method = method
 
934
        self.mname = method.__name__
 
935
        self.tname = type(method_self).__name__
 
936
 
 
937
 
 
938
class BinaryFile(BzrNewError):
 
939
    """File is binary but should be text."""
 
940
 
 
941
 
 
942
class IllegalPath(BzrNewError):
 
943
    """The path %(path)s is not permitted on this platform"""
 
944
 
 
945
    def __init__(self, path):
 
946
        BzrNewError.__init__(self)
 
947
        self.path = path
 
948
 
 
949
 
 
950
class TestamentMismatch(BzrNewError):
 
951
    """Testament did not match expected value.  
 
952
       For revision_id {%(revision_id)s}, expected {%(expected)s}, measured 
 
953
       {%(measured)s}
 
954
    """
 
955
    def __init__(self, revision_id, expected, measured):
 
956
        self.revision_id = revision_id
 
957
        self.expected = expected
 
958
        self.measured = measured
 
959
 
 
960
 
 
961
class NotABundle(BzrNewError):
 
962
    """Not a bzr revision-bundle: %(text)r"""
 
963
 
 
964
    def __init__(self, text):
 
965
        self.text = text
 
966
 
 
967
 
 
968
class BadBundle(Exception): pass
 
969
 
 
970
 
 
971
class MalformedHeader(BadBundle): pass
 
972
 
 
973
 
 
974
class MalformedPatches(BadBundle): pass
 
975
 
 
976
 
 
977
class MalformedFooter(BadBundle): pass