~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/errors.py

Fix BzrDir.create_workingtree for NULL_REVISION

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# (C) 2005 Canonical
2
 
 
 
1
# Copyright (C) 2005, 2006 Canonical
 
2
#
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.
7
 
 
 
7
#
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.
12
 
 
 
12
#
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
16
16
 
17
17
"""Exceptions for bzr, and reporting of them.
18
18
 
 
19
There are 3 different classes of error:
 
20
 
 
21
 * KeyboardInterrupt, and OSError with EPIPE - the program terminates 
 
22
   with an appropriate short message
 
23
 
 
24
 * User errors, indicating a problem caused by the user such as a bad URL.
 
25
   These are printed in a short form.
 
26
 
 
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.
 
30
 
19
31
Exceptions are caught at a high level to report errors to the user, and
20
32
might also be caught inside the program.  Therefore it needs to be
21
33
possible to convert them to a meaningful string, and also for them to be
34
46
... except:
35
47
...   print sys.exc_type
36
48
...   print sys.exc_value
37
 
...   path = getattr(sys.exc_value, 'path')
 
49
...   path = getattr(sys.exc_value, 'path', None)
38
50
...   if path is not None:
39
51
...     print path
40
52
bzrlib.errors.NotBranchError
44
56
Therefore:
45
57
 
46
58
 * 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.
 
59
   usefully distinguished.  If no callers are likely to want to catch
 
60
   one but not another, don't worry about them.
 
61
 
 
62
 * the __str__ method should generate something useful; BzrError provides
 
63
   a good default implementation
 
64
 
 
65
Exception strings should start with a capital letter and should not have a
 
66
final fullstop.
54
67
"""
55
68
 
 
69
from warnings import warn
 
70
 
 
71
from bzrlib.patches import (PatchSyntax, 
 
72
                            PatchConflict, 
 
73
                            MalformedPatchHeader,
 
74
                            MalformedHunkHeader,
 
75
                            MalformedLine,)
 
76
 
 
77
 
56
78
# based on Scott James Remnant's hct error classes
57
79
 
58
80
# TODO: is there any value in providing the .args field used by standard
66
88
# TODO: Convert all the other error classes here to BzrNewError, and eliminate
67
89
# the old one.
68
90
 
 
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.
 
94
 
69
95
 
70
96
class BzrError(StandardError):
 
97
    
 
98
    is_user_error = True
 
99
    
71
100
    def __str__(self):
72
101
        # XXX: Should we show the exception class in 
73
102
        # exceptions that don't provide their own message?  
97
126
 
98
127
    def __str__(self):
99
128
        try:
100
 
            return self.__doc__ % self.__dict__
 
129
            # __str__() should always return a 'str' object
 
130
            # never a 'unicode' object.
 
131
            s = self.__doc__ % self.__dict__
 
132
            if isinstance(s, unicode):
 
133
                return s.encode('utf8')
 
134
            return s
101
135
        except (NameError, ValueError, KeyError), e:
102
136
            return 'Unprintable exception %s: %s' \
103
137
                % (self.__class__.__name__, str(e))
105
139
 
106
140
class BzrCheckError(BzrNewError):
107
141
    """Internal check failed: %(message)s"""
 
142
 
 
143
    is_user_error = False
 
144
 
108
145
    def __init__(self, message):
109
146
        BzrNewError.__init__(self)
110
147
        self.message = message
112
149
 
113
150
class InvalidEntryName(BzrNewError):
114
151
    """Invalid entry name: %(name)s"""
 
152
 
 
153
    is_user_error = False
 
154
 
115
155
    def __init__(self, name):
116
156
        BzrNewError.__init__(self)
117
157
        self.name = name
126
166
 
127
167
class InvalidRevisionId(BzrNewError):
128
168
    """Invalid revision-id {%(revision_id)s} in %(branch)s"""
 
169
 
129
170
    def __init__(self, revision_id, branch):
 
171
        # branch can be any string or object with __str__ defined
130
172
        BzrNewError.__init__(self)
131
173
        self.revision_id = revision_id
132
174
        self.branch = branch
133
175
 
134
176
 
135
177
class NoWorkingTree(BzrNewError):
136
 
    """No WorkingTree exists for %s(base)."""
 
178
    """No WorkingTree exists for %(base)s."""
137
179
    
138
180
    def __init__(self, base):
139
181
        BzrNewError.__init__(self)
140
182
        self.base = base
141
183
 
142
184
 
143
 
class BzrCommandError(BzrError):
144
 
    # Error from malformed user command
145
 
    # This is being misused as a generic exception
146
 
    # pleae subclass. RBC 20051030
 
185
class NotLocalUrl(BzrNewError):
 
186
    """%(url)s is not a local path."""
 
187
    
 
188
    def __init__(self, url):
 
189
        BzrNewError.__init__(self)
 
190
        self.url = url
 
191
 
 
192
 
 
193
class BzrCommandError(BzrNewError):
 
194
    """Error from user command"""
 
195
 
 
196
    is_user_error = True
 
197
 
 
198
    # Error from malformed user command; please avoid raising this as a
 
199
    # generic exception not caused by user input.
147
200
    #
148
201
    # I think it's a waste of effort to differentiate between errors that
149
202
    # are not intended to be caught anyway.  UI code need not subclass
150
203
    # BzrCommandError, and non-UI code should not throw a subclass of
151
204
    # BzrCommandError.  ADHB 20051211
 
205
    def __init__(self, msg):
 
206
        # Object.__str__() must return a real string
 
207
        # returning a Unicode string is a python error.
 
208
        if isinstance(msg, unicode):
 
209
            self.msg = msg.encode('utf8')
 
210
        else:
 
211
            self.msg = msg
 
212
 
152
213
    def __str__(self):
153
 
        return self.args[0]
 
214
        return self.msg
154
215
 
155
216
 
156
217
class BzrOptionError(BzrCommandError):
157
 
    """Some missing or otherwise incorrect option was supplied."""
 
218
    """Error in command line options"""
158
219
 
159
220
    
160
 
class StrictCommitFailed(Exception):
161
 
    """Commit refused because there are unknowns in the tree."""
162
 
 
163
 
 
 
221
class StrictCommitFailed(BzrNewError):
 
222
    """Commit refused because there are unknown files in the tree"""
 
223
 
 
224
 
 
225
# XXX: Should be unified with TransportError; they seem to represent the
 
226
# same thing
164
227
class PathError(BzrNewError):
165
228
    """Generic path error: %(path)r%(extra)s)"""
 
229
 
166
230
    def __init__(self, path, extra=None):
167
231
        BzrNewError.__init__(self)
168
232
        self.path = path
180
244
    """File exists: %(path)r%(extra)s"""
181
245
 
182
246
 
 
247
class DirectoryNotEmpty(PathError):
 
248
    """Directory not empty: %(path)r%(extra)s"""
 
249
 
 
250
 
 
251
class ResourceBusy(PathError):
 
252
    """Device or resource busy: %(path)r%(extra)s"""
 
253
 
 
254
 
183
255
class PermissionDenied(PathError):
184
256
    """Permission denied: %(path)r%(extra)s"""
185
257
 
186
258
 
 
259
class InvalidURL(PathError):
 
260
    """Invalid url supplied to transport: %(path)r%(extra)s"""
 
261
 
 
262
 
 
263
class InvalidURLJoin(PathError):
 
264
    """Invalid URL join request: %(args)s%(extra)s"""
 
265
 
 
266
    def __init__(self, msg, base, args):
 
267
        PathError.__init__(self, base, msg)
 
268
        self.args = [base]
 
269
        self.args.extend(args)
 
270
 
 
271
 
 
272
class UnsupportedProtocol(PathError):
 
273
    """Unsupported protocol for url "%(path)s"%(extra)s"""
 
274
 
 
275
    def __init__(self, url, extra):
 
276
        PathError.__init__(self, url, extra=extra)
 
277
 
 
278
 
187
279
class PathNotChild(BzrNewError):
188
280
    """Path %(path)r is not a child of path %(base)r%(extra)s"""
 
281
 
 
282
    is_user_error = False
 
283
 
189
284
    def __init__(self, path, base, extra=None):
190
285
        BzrNewError.__init__(self)
191
286
        self.path = path
196
291
            self.extra = ''
197
292
 
198
293
 
199
 
class NotBranchError(BzrNewError):
 
294
class InvalidNormalization(PathError):
 
295
    """Path %(path)r is not unicode normalized"""
 
296
 
 
297
 
 
298
# TODO: This is given a URL; we try to unescape it but doing that from inside
 
299
# the exception object is a bit undesirable.
 
300
# TODO: Probably this behavior of should be a common superclass 
 
301
class NotBranchError(PathError):
200
302
    """Not a branch: %(path)s"""
 
303
 
201
304
    def __init__(self, path):
 
305
       import bzrlib.urlutils as urlutils
 
306
       self.path = urlutils.unescape_for_display(path, 'ascii')
 
307
 
 
308
 
 
309
class AlreadyBranchError(PathError):
 
310
    """Already a branch: %(path)s."""
 
311
 
 
312
 
 
313
class BranchExistsWithoutWorkingTree(PathError):
 
314
    """Directory contains a branch, but no working tree \
 
315
(use bzr checkout if you wish to build a working tree): %(path)s"""
 
316
 
 
317
 
 
318
class AtomicFileAlreadyClosed(PathError):
 
319
    """'%(function)s' called on an AtomicFile after it was closed: %(path)s"""
 
320
 
 
321
    def __init__(self, path, function):
 
322
        PathError.__init__(self, path=path, extra=None)
 
323
        self.function = function
 
324
 
 
325
 
 
326
class InaccessibleParent(PathError):
 
327
    """Parent not accessible given base %(base)s and relative path %(path)s"""
 
328
 
 
329
    def __init__(self, path, base):
 
330
        PathError.__init__(self, path)
 
331
        self.base = base
 
332
 
 
333
 
 
334
class NoRepositoryPresent(BzrNewError):
 
335
    """No repository present: %(path)r"""
 
336
    def __init__(self, bzrdir):
202
337
        BzrNewError.__init__(self)
203
 
        self.path = path
 
338
        self.path = bzrdir.transport.clone('..').base
204
339
 
205
340
 
206
341
class FileInWrongBranch(BzrNewError):
207
342
    """File %(path)s in not in branch %(branch_base)s."""
 
343
 
208
344
    def __init__(self, branch, path):
209
345
        BzrNewError.__init__(self)
210
346
        self.branch = branch
212
348
        self.path = path
213
349
 
214
350
 
215
 
class UnsupportedFormatError(BzrError):
216
 
    """Specified path is a bzr branch that we cannot read."""
217
 
    def __str__(self):
218
 
        return 'unsupported branch format: %s' % self.args[0]
 
351
class UnsupportedFormatError(BzrNewError):
 
352
    """Unsupported branch format: %(format)s"""
 
353
 
 
354
 
 
355
class UnknownFormatError(BzrNewError):
 
356
    """Unknown branch format: %(format)r"""
 
357
 
 
358
 
 
359
class IncompatibleFormat(BzrNewError):
 
360
    """Format %(format)s is not compatible with .bzr version %(bzrdir)s."""
 
361
 
 
362
    def __init__(self, format, bzrdir_format):
 
363
        BzrNewError.__init__(self)
 
364
        self.format = format
 
365
        self.bzrdir = bzrdir_format
219
366
 
220
367
 
221
368
class NotVersionedError(BzrNewError):
225
372
        self.path = path
226
373
 
227
374
 
228
 
class BadFileKindError(BzrError):
229
 
    """Specified file is of a kind that cannot be added.
230
 
 
231
 
    (For example a symlink or device file.)"""
232
 
 
233
 
 
234
 
class ForbiddenFileError(BzrError):
235
 
    """Cannot operate on a file because it is a control file."""
236
 
 
237
 
 
238
 
class LockError(Exception):
239
 
    """Lock error"""
 
375
class PathsNotVersionedError(BzrNewError):
 
376
    # used when reporting several paths are not versioned
 
377
    """Path(s) are not versioned: %(paths_as_string)s"""
 
378
 
 
379
    def __init__(self, paths):
 
380
        from bzrlib.osutils import quotefn
 
381
        BzrNewError.__init__(self)
 
382
        self.paths = paths
 
383
        self.paths_as_string = ' '.join([quotefn(p) for p in paths])
 
384
 
 
385
 
 
386
class PathsDoNotExist(BzrNewError):
 
387
    """Path(s) do not exist: %(paths_as_string)s"""
 
388
 
 
389
    # used when reporting that paths are neither versioned nor in the working
 
390
    # tree
 
391
 
 
392
    def __init__(self, paths):
 
393
        # circular import
 
394
        from bzrlib.osutils import quotefn
 
395
        BzrNewError.__init__(self)
 
396
        self.paths = paths
 
397
        self.paths_as_string = ' '.join([quotefn(p) for p in paths])
 
398
 
 
399
 
 
400
class BadFileKindError(BzrNewError):
 
401
    """Cannot operate on %(filename)s of unsupported kind %(kind)s"""
 
402
 
 
403
 
 
404
class ForbiddenControlFileError(BzrNewError):
 
405
    """Cannot operate on %(filename)s because it is a control file"""
 
406
 
 
407
 
 
408
class LockError(BzrNewError):
 
409
    """Lock error: %(message)s"""
240
410
    # All exceptions from the lock/unlock functions should be from
241
411
    # this exception class.  They will be translated as necessary. The
242
412
    # original exception is available as e.original_error
 
413
    #
 
414
    # New code should prefer to raise specific subclasses
 
415
    def __init__(self, message):
 
416
        self.message = message
243
417
 
244
418
 
245
419
class CommitNotPossible(LockError):
246
420
    """A commit was attempted but we do not have a write lock open."""
 
421
    def __init__(self):
 
422
        pass
247
423
 
248
424
 
249
425
class AlreadyCommitted(LockError):
250
426
    """A rollback was requested, but is not able to be accomplished."""
 
427
    def __init__(self):
 
428
        pass
251
429
 
252
430
 
253
431
class ReadOnlyError(LockError):
254
 
    """A write attempt was made in a read only transaction."""
 
432
    """A write attempt was made in a read only transaction on %(obj)s"""
 
433
    def __init__(self, obj):
 
434
        self.obj = obj
 
435
 
 
436
 
 
437
class OutSideTransaction(BzrNewError):
 
438
    """A transaction related operation was attempted after the transaction finished."""
 
439
 
 
440
 
 
441
class ObjectNotLocked(LockError):
 
442
    """%(obj)r is not locked"""
 
443
 
 
444
    is_user_error = False
 
445
 
 
446
    # this can indicate that any particular object is not locked; see also
 
447
    # LockNotHeld which means that a particular *lock* object is not held by
 
448
    # the caller -- perhaps they should be unified.
 
449
    def __init__(self, obj):
 
450
        self.obj = obj
 
451
 
 
452
 
 
453
class ReadOnlyObjectDirtiedError(ReadOnlyError):
 
454
    """Cannot change object %(obj)r in read only transaction"""
 
455
    def __init__(self, obj):
 
456
        self.obj = obj
 
457
 
 
458
 
 
459
class UnlockableTransport(LockError):
 
460
    """Cannot lock: transport is read only: %(transport)s"""
 
461
    def __init__(self, transport):
 
462
        self.transport = transport
 
463
 
 
464
 
 
465
class LockContention(LockError):
 
466
    """Could not acquire lock %(lock)s"""
 
467
    # TODO: show full url for lock, combining the transport and relative bits?
 
468
    def __init__(self, lock):
 
469
        self.lock = lock
 
470
 
 
471
 
 
472
class LockBroken(LockError):
 
473
    """Lock was broken while still open: %(lock)s - check storage consistency!"""
 
474
    def __init__(self, lock):
 
475
        self.lock = lock
 
476
 
 
477
 
 
478
class LockBreakMismatch(LockError):
 
479
    """Lock was released and re-acquired before being broken: %(lock)s: held by %(holder)r, wanted to break %(target)r"""
 
480
    def __init__(self, lock, holder, target):
 
481
        self.lock = lock
 
482
        self.holder = holder
 
483
        self.target = target
 
484
 
 
485
 
 
486
class LockNotHeld(LockError):
 
487
    """Lock not held: %(lock)s"""
 
488
    def __init__(self, lock):
 
489
        self.lock = lock
255
490
 
256
491
 
257
492
class PointlessCommit(BzrNewError):
258
493
    """No changes to commit"""
259
494
 
 
495
 
 
496
class UpgradeReadonly(BzrNewError):
 
497
    """Upgrade URL cannot work with readonly URL's."""
 
498
 
 
499
 
 
500
class UpToDateFormat(BzrNewError):
 
501
    """The branch format %(format)s is already at the most recent format."""
 
502
 
 
503
    def __init__(self, format):
 
504
        BzrNewError.__init__(self)
 
505
        self.format = format
 
506
 
 
507
 
 
508
 
260
509
class StrictCommitFailed(Exception):
261
510
    """Commit refused because there are unknowns in the tree."""
262
511
 
263
 
class NoSuchRevision(BzrError):
 
512
 
 
513
class NoSuchRevision(BzrNewError):
 
514
    """Branch %(branch)s has no revision %(revision)s"""
 
515
 
 
516
    is_user_error = False
 
517
 
264
518
    def __init__(self, branch, revision):
265
519
        self.branch = branch
266
520
        self.revision = revision
267
 
        msg = "Branch %s has no revision %s" % (branch, revision)
268
 
        BzrError.__init__(self, msg)
269
521
 
270
522
 
271
523
class HistoryMissing(BzrError):
276
528
                          % (branch, object_type, object_id))
277
529
 
278
530
 
279
 
class DivergedBranches(BzrError):
 
531
class DivergedBranches(BzrNewError):
 
532
    "These branches have diverged.  Use the merge command to reconcile them."""
 
533
 
 
534
    is_user_error = True
 
535
 
280
536
    def __init__(self, branch1, branch2):
281
 
        BzrError.__init__(self, "These branches have diverged.  Try merge.")
282
537
        self.branch1 = branch1
283
538
        self.branch2 = branch2
284
539
 
285
540
 
286
 
class UnrelatedBranches(BzrCommandError):
287
 
    def __init__(self):
288
 
        msg = "Branches have no common ancestor, and no base revision"\
289
 
            " specified."
290
 
        BzrCommandError.__init__(self, msg)
291
 
 
292
 
class NoCommonAncestor(BzrError):
 
541
class UnrelatedBranches(BzrNewError):
 
542
    "Branches have no common ancestor, and no merge base revision was specified."
 
543
 
 
544
    is_user_error = True
 
545
 
 
546
 
 
547
class NoCommonAncestor(BzrNewError):
 
548
    "Revisions have no common ancestor: %(revision_a)s %(revision_b)s"
 
549
 
293
550
    def __init__(self, revision_a, revision_b):
294
 
        msg = "Revisions have no common ancestor: %s %s." \
295
 
            % (revision_a, revision_b) 
296
 
        BzrError.__init__(self, msg)
 
551
        self.revision_a = revision_a
 
552
        self.revision_b = revision_b
 
553
 
297
554
 
298
555
class NoCommonRoot(BzrError):
299
556
    def __init__(self, revision_a, revision_b):
301
558
            % (revision_a, revision_b) 
302
559
        BzrError.__init__(self, msg)
303
560
 
 
561
 
 
562
 
304
563
class NotAncestor(BzrError):
305
564
    def __init__(self, rev_id, not_ancestor_id):
306
565
        msg = "Revision %s is not an ancestor of %s" % (not_ancestor_id, 
319
578
 
320
579
class AmbiguousBase(BzrError):
321
580
    def __init__(self, bases):
322
 
        msg = "The correct base is unclear, becase %s are all equally close" %\
 
581
        warn("BzrError AmbiguousBase has been deprecated as of bzrlib 0.8.",
 
582
                DeprecationWarning)
 
583
        msg = "The correct base is unclear, because %s are all equally close" %\
323
584
            ", ".join(bases)
324
585
        BzrError.__init__(self, msg)
325
586
        self.bases = bases
326
587
 
 
588
 
327
589
class NoCommits(BzrError):
328
590
    def __init__(self, branch):
329
591
        msg = "Branch %s has no commits." % branch
330
592
        BzrError.__init__(self, msg)
331
593
 
 
594
 
332
595
class UnlistableStore(BzrError):
333
596
    def __init__(self, store):
334
597
        BzrError.__init__(self, "Store %s is not listable" % store)
335
598
 
 
599
 
 
600
 
336
601
class UnlistableBranch(BzrError):
337
602
    def __init__(self, br):
338
603
        BzrError.__init__(self, "Stores for branch %s are not listable" % br)
339
604
 
340
605
 
 
606
class BoundBranchOutOfDate(BzrNewError):
 
607
    """Bound branch %(branch)s is out of date with master branch %(master)s."""
 
608
    def __init__(self, branch, master):
 
609
        BzrNewError.__init__(self)
 
610
        self.branch = branch
 
611
        self.master = master
 
612
 
 
613
        
 
614
class CommitToDoubleBoundBranch(BzrNewError):
 
615
    """Cannot commit to branch %(branch)s. It is bound to %(master)s, which is bound to %(remote)s."""
 
616
    def __init__(self, branch, master, remote):
 
617
        BzrNewError.__init__(self)
 
618
        self.branch = branch
 
619
        self.master = master
 
620
        self.remote = remote
 
621
 
 
622
 
 
623
class OverwriteBoundBranch(BzrNewError):
 
624
    """Cannot pull --overwrite to a branch which is bound %(branch)s"""
 
625
    def __init__(self, branch):
 
626
        BzrNewError.__init__(self)
 
627
        self.branch = branch
 
628
 
 
629
 
 
630
class BoundBranchConnectionFailure(BzrNewError):
 
631
    """Unable to connect to target of bound branch %(branch)s => %(target)s: %(error)s"""
 
632
    def __init__(self, branch, target, error):
 
633
        BzrNewError.__init__(self)
 
634
        self.branch = branch
 
635
        self.target = target
 
636
        self.error = error
 
637
 
 
638
 
341
639
class WeaveError(BzrNewError):
342
640
    """Error in processing weave: %(message)s"""
 
641
 
343
642
    def __init__(self, message=None):
344
643
        BzrNewError.__init__(self)
345
644
        self.message = message
348
647
class WeaveRevisionAlreadyPresent(WeaveError):
349
648
    """Revision {%(revision_id)s} already present in %(weave)s"""
350
649
    def __init__(self, revision_id, weave):
 
650
 
351
651
        WeaveError.__init__(self)
352
652
        self.revision_id = revision_id
353
653
        self.weave = weave
355
655
 
356
656
class WeaveRevisionNotPresent(WeaveError):
357
657
    """Revision {%(revision_id)s} not present in %(weave)s"""
 
658
 
358
659
    def __init__(self, revision_id, weave):
359
660
        WeaveError.__init__(self)
360
661
        self.revision_id = revision_id
363
664
 
364
665
class WeaveFormatError(WeaveError):
365
666
    """Weave invariant violated: %(what)s"""
 
667
 
366
668
    def __init__(self, what):
367
669
        WeaveError.__init__(self)
368
670
        self.what = what
376
678
    """Text did not match it's checksum: %(message)s"""
377
679
 
378
680
 
 
681
class WeaveTextDiffers(WeaveError):
 
682
    """Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
 
683
 
 
684
    def __init__(self, revision_id, weave_a, weave_b):
 
685
        WeaveError.__init__(self)
 
686
        self.revision_id = revision_id
 
687
        self.weave_a = weave_a
 
688
        self.weave_b = weave_b
 
689
 
 
690
 
 
691
class WeaveTextDiffers(WeaveError):
 
692
    """Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
 
693
 
 
694
    def __init__(self, revision_id, weave_a, weave_b):
 
695
        WeaveError.__init__(self)
 
696
        self.revision_id = revision_id
 
697
        self.weave_a = weave_a
 
698
        self.weave_b = weave_b
 
699
 
 
700
 
 
701
class VersionedFileError(BzrNewError):
 
702
    """Versioned file error."""
 
703
 
 
704
 
 
705
class RevisionNotPresent(VersionedFileError):
 
706
    """Revision {%(revision_id)s} not present in %(file_id)s."""
 
707
 
 
708
    def __init__(self, revision_id, file_id):
 
709
        VersionedFileError.__init__(self)
 
710
        self.revision_id = revision_id
 
711
        self.file_id = file_id
 
712
 
 
713
 
 
714
class RevisionAlreadyPresent(VersionedFileError):
 
715
    """Revision {%(revision_id)s} already present in %(file_id)s."""
 
716
 
 
717
    def __init__(self, revision_id, file_id):
 
718
        VersionedFileError.__init__(self)
 
719
        self.revision_id = revision_id
 
720
        self.file_id = file_id
 
721
 
 
722
 
 
723
class KnitError(BzrNewError):
 
724
    """Knit error"""
 
725
 
 
726
 
 
727
class KnitHeaderError(KnitError):
 
728
    """Knit header error: %(badline)r unexpected"""
 
729
 
 
730
    def __init__(self, badline):
 
731
        KnitError.__init__(self)
 
732
        self.badline = badline
 
733
 
 
734
 
 
735
class KnitCorrupt(KnitError):
 
736
    """Knit %(filename)s corrupt: %(how)s"""
 
737
 
 
738
    def __init__(self, filename, how):
 
739
        KnitError.__init__(self)
 
740
        self.filename = filename
 
741
        self.how = how
 
742
 
 
743
 
379
744
class NoSuchExportFormat(BzrNewError):
380
745
    """Export format %(format)r not supported"""
381
746
    def __init__(self, format):
383
748
        self.format = format
384
749
 
385
750
 
386
 
class TransportError(BzrError):
387
 
    """All errors thrown by Transport implementations should derive
388
 
    from this class.
389
 
    """
 
751
class TransportError(BzrNewError):
 
752
    """Transport error: %(msg)s %(orig_error)s"""
 
753
 
390
754
    def __init__(self, msg=None, orig_error=None):
391
755
        if msg is None and orig_error is not None:
392
756
            msg = str(orig_error)
393
 
        BzrError.__init__(self, msg)
 
757
        if orig_error is None:
 
758
            orig_error = ''
 
759
        if msg is None:
 
760
            msg =  ''
394
761
        self.msg = msg
395
762
        self.orig_error = orig_error
 
763
        BzrNewError.__init__(self)
 
764
 
396
765
 
397
766
# A set of semi-meaningful errors which can be thrown
398
767
class TransportNotPossible(TransportError):
399
 
    """This is for transports where a specific function is explicitly not
400
 
    possible. Such as pushing files to an HTTP server.
401
 
    """
402
 
    pass
 
768
    """Transport operation not possible: %(msg)s %(orig_error)%"""
403
769
 
404
770
 
405
771
class ConnectionError(TransportError):
406
 
    """A connection problem prevents file retrieval.
407
 
    This does not indicate whether the file exists or not; it indicates that a
408
 
    precondition for requesting the file was not met.
409
 
    """
410
 
    def __init__(self, msg=None, orig_error=None):
411
 
        TransportError.__init__(self, msg=msg, orig_error=orig_error)
 
772
    """Connection error: %(msg)s %(orig_error)s"""
412
773
 
413
774
 
414
775
class ConnectionReset(TransportError):
415
 
    """The connection has been closed."""
416
 
    pass
 
776
    """Connection closed: %(msg)s %(orig_error)s"""
 
777
 
 
778
 
 
779
class InvalidRange(TransportError):
 
780
    """Invalid range access."""
 
781
    
 
782
    def __init__(self, path, offset):
 
783
        TransportError.__init__(self, ("Invalid range access in %s at %d"
 
784
                                       % (path, offset)))
 
785
 
 
786
 
 
787
class InvalidHttpResponse(TransportError):
 
788
    """Invalid http response for %(path)s: %(msg)s"""
 
789
 
 
790
    def __init__(self, path, msg, orig_error=None):
 
791
        self.path = path
 
792
        TransportError.__init__(self, msg, orig_error=orig_error)
 
793
 
 
794
 
 
795
class InvalidHttpRange(InvalidHttpResponse):
 
796
    """Invalid http range "%(range)s" for %(path)s: %(msg)s"""
 
797
    
 
798
    def __init__(self, path, range, msg):
 
799
        self.range = range
 
800
        InvalidHttpResponse.__init__(self, path, msg)
 
801
 
 
802
 
 
803
class InvalidHttpContentType(InvalidHttpResponse):
 
804
    """Invalid http Content-type "%(ctype)s" for %(path)s: %(msg)s"""
 
805
    
 
806
    def __init__(self, path, ctype, msg):
 
807
        self.ctype = ctype
 
808
        InvalidHttpResponse.__init__(self, path, msg)
 
809
 
417
810
 
418
811
class ConflictsInTree(BzrError):
419
812
    def __init__(self):
420
813
        BzrError.__init__(self, "Working tree has conflicts.")
421
814
 
 
815
 
422
816
class ParseConfigError(BzrError):
423
817
    def __init__(self, errors, filename):
424
818
        if filename is None:
427
821
            (filename, ('\n'.join(e.message for e in errors)))
428
822
        BzrError.__init__(self, message)
429
823
 
 
824
 
430
825
class SigningFailed(BzrError):
431
826
    def __init__(self, command_line):
432
827
        BzrError.__init__(self, "Failed to gpg sign data with command '%s'"
433
828
                               % command_line)
434
829
 
 
830
 
435
831
class WorkingTreeNotRevision(BzrError):
436
832
    def __init__(self, tree):
437
833
        BzrError.__init__(self, "The working tree for %s has changed since"
438
834
                          " last commit, but weave merge requires that it be"
439
835
                          " unchanged." % tree.basedir)
440
836
 
 
837
 
441
838
class CantReprocessAndShowBase(BzrNewError):
442
839
    """Can't reprocess and show base.
443
840
Reprocessing obscures relationship of conflicting lines to base."""
444
841
 
 
842
 
445
843
class GraphCycleError(BzrNewError):
446
844
    """Cycle in graph %(graph)r"""
447
845
    def __init__(self, graph):
463
861
    This should never escape bzr, so does not need to be printable.
464
862
    """
465
863
 
 
864
 
 
865
class NoBundleFound(BzrNewError):
 
866
    """No bundle was found in %(filename)s"""
 
867
    def __init__(self, filename):
 
868
        BzrNewError.__init__(self)
 
869
        self.filename = filename
 
870
 
 
871
 
 
872
class BundleNotSupported(BzrNewError):
 
873
    """Unable to handle bundle version %(version)s: %(msg)s"""
 
874
    def __init__(self, version, msg):
 
875
        BzrNewError.__init__(self)
 
876
        self.version = version
 
877
        self.msg = msg
 
878
 
 
879
 
466
880
class MissingText(BzrNewError):
467
881
    """Branch %(base)s is missing revision %(text_revision)s of %(file_id)s"""
468
882
 
474
888
        self.file_id = file_id
475
889
 
476
890
 
 
891
class DuplicateKey(BzrNewError):
 
892
    """Key %(key)s is already present in map"""
 
893
 
 
894
 
 
895
class MalformedTransform(BzrNewError):
 
896
    """Tree transform is malformed %(conflicts)r"""
 
897
 
 
898
 
477
899
class BzrBadParameter(BzrNewError):
478
 
    """Parameter %(param)s is neither unicode nor utf8."""
 
900
    """A bad parameter : %(param)s is not usable.
479
901
    
 
902
    This exception should never be thrown, but it is a base class for all
 
903
    parameter-to-function errors.
 
904
    """
480
905
    def __init__(self, param):
481
906
        BzrNewError.__init__(self)
482
907
        self.param = param
 
908
 
 
909
 
 
910
class BzrBadParameterNotUnicode(BzrBadParameter):
 
911
    """Parameter %(param)s is neither unicode nor utf8."""
 
912
 
 
913
 
 
914
class ReusingTransform(BzrNewError):
 
915
    """Attempt to reuse a transform that has already been applied."""
 
916
 
 
917
 
 
918
class CantMoveRoot(BzrNewError):
 
919
    """Moving the root directory is not supported at this time"""
 
920
 
 
921
 
 
922
class BzrBadParameterNotString(BzrBadParameter):
 
923
    """Parameter %(param)s is not a string or unicode string."""
 
924
 
 
925
 
 
926
class BzrBadParameterMissing(BzrBadParameter):
 
927
    """Parameter $(param)s is required but not present."""
 
928
 
 
929
 
 
930
class BzrBadParameterUnicode(BzrBadParameter):
 
931
    """Parameter %(param)s is unicode but only byte-strings are permitted."""
 
932
 
 
933
 
 
934
class BzrBadParameterContainsNewline(BzrBadParameter):
 
935
    """Parameter %(param)s contains a newline."""
 
936
 
 
937
 
 
938
class DependencyNotPresent(BzrNewError):
 
939
    """Unable to import library "%(library)s": %(error)s"""
 
940
 
 
941
    def __init__(self, library, error):
 
942
        BzrNewError.__init__(self, library=library, error=error)
 
943
 
 
944
 
 
945
class ParamikoNotPresent(DependencyNotPresent):
 
946
    """Unable to import paramiko (required for sftp support): %(error)s"""
 
947
 
 
948
    def __init__(self, error):
 
949
        DependencyNotPresent.__init__(self, 'paramiko', error)
 
950
 
 
951
 
 
952
class UninitializableFormat(BzrNewError):
 
953
    """Format %(format)s cannot be initialised by this version of bzr."""
 
954
 
 
955
    def __init__(self, format):
 
956
        BzrNewError.__init__(self)
 
957
        self.format = format
 
958
 
 
959
 
 
960
class NoDiff(BzrNewError):
 
961
    """Diff is not installed on this machine: %(msg)s"""
 
962
 
 
963
    def __init__(self, msg):
 
964
        BzrNewError.__init__(self, msg=msg)
 
965
 
 
966
 
 
967
class NoDiff3(BzrNewError):
 
968
    """Diff3 is not installed on this machine."""
 
969
 
 
970
 
 
971
class ExistingLimbo(BzrNewError):
 
972
    """This tree contains left-over files from a failed operation.
 
973
    Please examine %(limbo_dir)s to see if it contains any files you wish to
 
974
    keep, and delete it when you are done.
 
975
    """
 
976
    def __init__(self, limbo_dir):
 
977
       BzrNewError.__init__(self)
 
978
       self.limbo_dir = limbo_dir
 
979
 
 
980
 
 
981
class ImmortalLimbo(BzrNewError):
 
982
    """Unable to delete transform temporary directory $(limbo_dir)s.
 
983
    Please examine %(limbo_dir)s to see if it contains any files you wish to
 
984
    keep, and delete it when you are done.
 
985
    """
 
986
    def __init__(self, limbo_dir):
 
987
       BzrNewError.__init__(self)
 
988
       self.limbo_dir = limbo_dir
 
989
 
 
990
 
 
991
class OutOfDateTree(BzrNewError):
 
992
    """Working tree is out of date, please run 'bzr update'."""
 
993
 
 
994
    def __init__(self, tree):
 
995
        BzrNewError.__init__(self)
 
996
        self.tree = tree
 
997
 
 
998
 
 
999
class MergeModifiedFormatError(BzrNewError):
 
1000
    """Error in merge modified format"""
 
1001
 
 
1002
 
 
1003
class ConflictFormatError(BzrNewError):
 
1004
    """Format error in conflict listings"""
 
1005
 
 
1006
 
 
1007
class CorruptRepository(BzrNewError):
 
1008
    """An error has been detected in the repository %(repo_path)s.
 
1009
Please run bzr reconcile on this repository."""
 
1010
 
 
1011
    def __init__(self, repo):
 
1012
        BzrNewError.__init__(self)
 
1013
        self.repo_path = repo.bzrdir.root_transport.base
 
1014
 
 
1015
 
 
1016
class UpgradeRequired(BzrNewError):
 
1017
    """To use this feature you must upgrade your branch at %(path)s."""
 
1018
 
 
1019
    def __init__(self, path):
 
1020
        BzrNewError.__init__(self)
 
1021
        self.path = path
 
1022
 
 
1023
 
 
1024
class LocalRequiresBoundBranch(BzrNewError):
 
1025
    """Cannot perform local-only commits on unbound branches."""
 
1026
 
 
1027
 
 
1028
class MissingProgressBarFinish(BzrNewError):
 
1029
    """A nested progress bar was not 'finished' correctly."""
 
1030
 
 
1031
 
 
1032
class InvalidProgressBarType(BzrNewError):
 
1033
    """Environment variable BZR_PROGRESS_BAR='%(bar_type)s is not a supported type
 
1034
Select one of: %(valid_types)s"""
 
1035
 
 
1036
    def __init__(self, bar_type, valid_types):
 
1037
        BzrNewError.__init__(self, bar_type=bar_type, valid_types=valid_types)
 
1038
 
 
1039
 
 
1040
class UnsupportedOperation(BzrNewError):
 
1041
    """The method %(mname)s is not supported on objects of type %(tname)s."""
 
1042
    def __init__(self, method, method_self):
 
1043
        self.method = method
 
1044
        self.mname = method.__name__
 
1045
        self.tname = type(method_self).__name__
 
1046
 
 
1047
 
 
1048
class BinaryFile(BzrNewError):
 
1049
    """File is binary but should be text."""
 
1050
 
 
1051
 
 
1052
class IllegalPath(BzrNewError):
 
1053
    """The path %(path)s is not permitted on this platform"""
 
1054
 
 
1055
    def __init__(self, path):
 
1056
        BzrNewError.__init__(self)
 
1057
        self.path = path
 
1058
 
 
1059
 
 
1060
class TestamentMismatch(BzrNewError):
 
1061
    """Testament did not match expected value.  
 
1062
       For revision_id {%(revision_id)s}, expected {%(expected)s}, measured 
 
1063
       {%(measured)s}
 
1064
    """
 
1065
    def __init__(self, revision_id, expected, measured):
 
1066
        self.revision_id = revision_id
 
1067
        self.expected = expected
 
1068
        self.measured = measured
 
1069
 
 
1070
 
 
1071
class NotABundle(BzrNewError):
 
1072
    """Not a bzr revision-bundle: %(text)r"""
 
1073
 
 
1074
    def __init__(self, text):
 
1075
        BzrNewError.__init__(self)
 
1076
        self.text = text
 
1077
 
 
1078
 
 
1079
class BadBundle(BzrNewError): 
 
1080
    """Bad bzr revision-bundle: %(text)r"""
 
1081
 
 
1082
    def __init__(self, text):
 
1083
        BzrNewError.__init__(self)
 
1084
        self.text = text
 
1085
 
 
1086
 
 
1087
class MalformedHeader(BadBundle): 
 
1088
    """Malformed bzr revision-bundle header: %(text)r"""
 
1089
 
 
1090
    def __init__(self, text):
 
1091
        BzrNewError.__init__(self)
 
1092
        self.text = text
 
1093
 
 
1094
 
 
1095
class MalformedPatches(BadBundle): 
 
1096
    """Malformed patches in bzr revision-bundle: %(text)r"""
 
1097
 
 
1098
    def __init__(self, text):
 
1099
        BzrNewError.__init__(self)
 
1100
        self.text = text
 
1101
 
 
1102
 
 
1103
class MalformedFooter(BadBundle): 
 
1104
    """Malformed footer in bzr revision-bundle: %(text)r"""
 
1105
 
 
1106
    def __init__(self, text):
 
1107
        BzrNewError.__init__(self)
 
1108
        self.text = text
 
1109
 
 
1110
 
 
1111
class UnsupportedEOLMarker(BadBundle):
 
1112
    """End of line marker was not \\n in bzr revision-bundle"""    
 
1113
 
 
1114
    def __init__(self):
 
1115
        BzrNewError.__init__(self)
 
1116
 
 
1117
 
 
1118
class UnknownSSH(BzrNewError):
 
1119
    """Unrecognised value for BZR_SSH environment variable: %(vendor)s"""
 
1120
 
 
1121
    def __init__(self, vendor):
 
1122
        BzrNewError.__init__(self)
 
1123
        self.vendor = vendor
 
1124
 
 
1125
 
 
1126
class GhostRevisionUnusableHere(BzrNewError):
 
1127
    """Ghost revision {%(revision_id)s} cannot be used here."""
 
1128
 
 
1129
    def __init__(self, revision_id):
 
1130
        BzrNewError.__init__(self)
 
1131
        self.revision_id = revision_id