/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/errors.py

Nearly complete .bzr/checkout splitout.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# (C) 2005 Canonical
 
2
 
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
 
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
 
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
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')
 
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
# based on Scott James Remnant's hct error classes
 
57
 
 
58
# TODO: is there any value in providing the .args field used by standard
 
59
# python exceptions?   A list of values with no names seems less useful 
 
60
# to me.
 
61
 
 
62
# TODO: Perhaps convert the exception to a string at the moment it's 
 
63
# constructed to make sure it will succeed.  But that says nothing about
 
64
# exceptions that are never raised.
 
65
 
 
66
# TODO: Convert all the other error classes here to BzrNewError, and eliminate
 
67
# the old one.
 
68
 
 
69
 
 
70
class BzrError(StandardError):
 
71
    def __str__(self):
 
72
        # XXX: Should we show the exception class in 
 
73
        # exceptions that don't provide their own message?  
 
74
        # maybe it should be done at a higher level
 
75
        ## n = self.__class__.__name__ + ': '
 
76
        n = ''
 
77
        if len(self.args) == 1:
 
78
            return str(self.args[0])
 
79
        elif len(self.args) == 2:
 
80
            # further explanation or suggestions
 
81
            try:
 
82
                return n + '\n  '.join([self.args[0]] + self.args[1])
 
83
            except TypeError:
 
84
                return n + "%r" % self
 
85
        else:
 
86
            return n + `self.args`
 
87
 
 
88
 
 
89
class BzrNewError(BzrError):
 
90
    """bzr error"""
 
91
    # base classes should override the docstring with their human-
 
92
    # readable explanation
 
93
 
 
94
    def __init__(self, **kwds):
 
95
        for key, value in kwds.items():
 
96
            setattr(self, key, value)
 
97
 
 
98
    def __str__(self):
 
99
        try:
 
100
            return self.__doc__ % self.__dict__
 
101
        except (NameError, ValueError, KeyError), e:
 
102
            return 'Unprintable exception %s: %s' \
 
103
                % (self.__class__.__name__, str(e))
 
104
 
 
105
 
 
106
class BzrCheckError(BzrNewError):
 
107
    """Internal check failed: %(message)s"""
 
108
    def __init__(self, message):
 
109
        BzrNewError.__init__(self)
 
110
        self.message = message
 
111
 
 
112
 
 
113
class InvalidEntryName(BzrNewError):
 
114
    """Invalid entry name: %(name)s"""
 
115
    def __init__(self, name):
 
116
        BzrNewError.__init__(self)
 
117
        self.name = name
 
118
 
 
119
 
 
120
class InvalidRevisionNumber(BzrNewError):
 
121
    """Invalid revision number %(revno)d"""
 
122
    def __init__(self, revno):
 
123
        BzrNewError.__init__(self)
 
124
        self.revno = revno
 
125
 
 
126
 
 
127
class InvalidRevisionId(BzrNewError):
 
128
    """Invalid revision-id {%(revision_id)s} in %(branch)s"""
 
129
    def __init__(self, revision_id, branch):
 
130
        BzrNewError.__init__(self)
 
131
        self.revision_id = revision_id
 
132
        self.branch = branch
 
133
 
 
134
 
 
135
class NoWorkingTree(BzrNewError):
 
136
    """No WorkingTree exists for %s(base)."""
 
137
    
 
138
    def __init__(self, base):
 
139
        BzrNewError.__init__(self)
 
140
        self.base = base
 
141
 
 
142
 
 
143
class NotLocalUrl(BzrNewError):
 
144
    """%s(url) is not a local path."""
 
145
    
 
146
    def __init__(self, url):
 
147
        BzrNewError.__init__(self)
 
148
        self.url = url
 
149
 
 
150
 
 
151
class BzrCommandError(BzrError):
 
152
    # Error from malformed user command
 
153
    # This is being misused as a generic exception
 
154
    # pleae subclass. RBC 20051030
 
155
    #
 
156
    # I think it's a waste of effort to differentiate between errors that
 
157
    # are not intended to be caught anyway.  UI code need not subclass
 
158
    # BzrCommandError, and non-UI code should not throw a subclass of
 
159
    # BzrCommandError.  ADHB 20051211
 
160
    def __str__(self):
 
161
        return self.args[0]
 
162
 
 
163
 
 
164
class BzrOptionError(BzrCommandError):
 
165
    """Some missing or otherwise incorrect option was supplied."""
 
166
 
 
167
    
 
168
class StrictCommitFailed(Exception):
 
169
    """Commit refused because there are unknowns in the tree."""
 
170
 
 
171
 
 
172
class PathError(BzrNewError):
 
173
    """Generic path error: %(path)r%(extra)s)"""
 
174
    def __init__(self, path, extra=None):
 
175
        BzrNewError.__init__(self)
 
176
        self.path = path
 
177
        if extra:
 
178
            self.extra = ': ' + str(extra)
 
179
        else:
 
180
            self.extra = ''
 
181
 
 
182
 
 
183
class NoSuchFile(PathError):
 
184
    """No such file: %(path)r%(extra)s"""
 
185
 
 
186
 
 
187
class FileExists(PathError):
 
188
    """File exists: %(path)r%(extra)s"""
 
189
 
 
190
 
 
191
class PermissionDenied(PathError):
 
192
    """Permission denied: %(path)r%(extra)s"""
 
193
 
 
194
 
 
195
class PathNotChild(BzrNewError):
 
196
    """Path %(path)r is not a child of path %(base)r%(extra)s"""
 
197
    def __init__(self, path, base, extra=None):
 
198
        BzrNewError.__init__(self)
 
199
        self.path = path
 
200
        self.base = base
 
201
        if extra:
 
202
            self.extra = ': ' + str(extra)
 
203
        else:
 
204
            self.extra = ''
 
205
 
 
206
 
 
207
class NotBranchError(BzrNewError):
 
208
    """Not a branch: %(path)s"""
 
209
    def __init__(self, path):
 
210
        BzrNewError.__init__(self)
 
211
        self.path = path
 
212
 
 
213
 
 
214
class FileInWrongBranch(BzrNewError):
 
215
    """File %(path)s in not in branch %(branch_base)s."""
 
216
 
 
217
    def __init__(self, branch, path):
 
218
        BzrNewError.__init__(self)
 
219
        self.branch = branch
 
220
        self.branch_base = branch.base
 
221
        self.path = path
 
222
 
 
223
 
 
224
class UnsupportedFormatError(BzrError):
 
225
    """Specified path is a bzr branch that we recognize but cannot read."""
 
226
    def __str__(self):
 
227
        return 'unsupported branch format: %s' % self.args[0]
 
228
 
 
229
 
 
230
class UnknownFormatError(BzrError):
 
231
    """Specified path is a bzr branch whose format we do not recognize."""
 
232
    def __str__(self):
 
233
        return 'unknown branch format: %s' % self.args[0]
 
234
 
 
235
 
 
236
class IncompatibleFormat(BzrNewError):
 
237
    """Format %(format)s is not compatible with .bzr version %(bzrdir)s."""
 
238
 
 
239
    def __init__(self, format, bzrdir_format):
 
240
        BzrNewError.__init__(self)
 
241
        self.format = format
 
242
        self.bzrdir = bzrdir_format
 
243
 
 
244
 
 
245
class NotVersionedError(BzrNewError):
 
246
    """%(path)s is not versioned"""
 
247
    def __init__(self, path):
 
248
        BzrNewError.__init__(self)
 
249
        self.path = path
 
250
 
 
251
 
 
252
class BadFileKindError(BzrError):
 
253
    """Specified file is of a kind that cannot be added.
 
254
 
 
255
    (For example a symlink or device file.)"""
 
256
 
 
257
 
 
258
class ForbiddenFileError(BzrError):
 
259
    """Cannot operate on a file because it is a control file."""
 
260
 
 
261
 
 
262
class LockError(Exception):
 
263
    """Lock error"""
 
264
    # All exceptions from the lock/unlock functions should be from
 
265
    # this exception class.  They will be translated as necessary. The
 
266
    # original exception is available as e.original_error
 
267
 
 
268
 
 
269
class CommitNotPossible(LockError):
 
270
    """A commit was attempted but we do not have a write lock open."""
 
271
 
 
272
 
 
273
class AlreadyCommitted(LockError):
 
274
    """A rollback was requested, but is not able to be accomplished."""
 
275
 
 
276
 
 
277
class ReadOnlyError(LockError):
 
278
    """A write attempt was made in a read only transaction."""
 
279
 
 
280
 
 
281
class PointlessCommit(BzrNewError):
 
282
    """No changes to commit"""
 
283
 
 
284
 
 
285
class UpgradeReadonly(BzrNewError):
 
286
    """Upgrade URL cannot work with readonly URL's."""
 
287
 
 
288
 
 
289
class StrictCommitFailed(Exception):
 
290
    """Commit refused because there are unknowns in the tree."""
 
291
 
 
292
 
 
293
class NoSuchRevision(BzrError):
 
294
    def __init__(self, branch, revision):
 
295
        self.branch = branch
 
296
        self.revision = revision
 
297
        msg = "Branch %s has no revision %s" % (branch, revision)
 
298
        BzrError.__init__(self, msg)
 
299
 
 
300
 
 
301
class HistoryMissing(BzrError):
 
302
    def __init__(self, branch, object_type, object_id):
 
303
        self.branch = branch
 
304
        BzrError.__init__(self,
 
305
                          '%s is missing %s {%s}'
 
306
                          % (branch, object_type, object_id))
 
307
 
 
308
 
 
309
class DivergedBranches(BzrError):
 
310
    def __init__(self, branch1, branch2):
 
311
        BzrError.__init__(self, "These branches have diverged.  Try merge.")
 
312
        self.branch1 = branch1
 
313
        self.branch2 = branch2
 
314
 
 
315
 
 
316
class UnrelatedBranches(BzrCommandError):
 
317
    def __init__(self):
 
318
        msg = "Branches have no common ancestor, and no base revision"\
 
319
            " specified."
 
320
        BzrCommandError.__init__(self, msg)
 
321
 
 
322
class NoCommonAncestor(BzrError):
 
323
    def __init__(self, revision_a, revision_b):
 
324
        msg = "Revisions have no common ancestor: %s %s." \
 
325
            % (revision_a, revision_b) 
 
326
        BzrError.__init__(self, msg)
 
327
 
 
328
class NoCommonRoot(BzrError):
 
329
    def __init__(self, revision_a, revision_b):
 
330
        msg = "Revisions are not derived from the same root: %s %s." \
 
331
            % (revision_a, revision_b) 
 
332
        BzrError.__init__(self, msg)
 
333
 
 
334
class NotAncestor(BzrError):
 
335
    def __init__(self, rev_id, not_ancestor_id):
 
336
        msg = "Revision %s is not an ancestor of %s" % (not_ancestor_id, 
 
337
                                                        rev_id)
 
338
        BzrError.__init__(self, msg)
 
339
        self.rev_id = rev_id
 
340
        self.not_ancestor_id = not_ancestor_id
 
341
 
 
342
 
 
343
class InstallFailed(BzrError):
 
344
    def __init__(self, revisions):
 
345
        msg = "Could not install revisions:\n%s" % " ,".join(revisions)
 
346
        BzrError.__init__(self, msg)
 
347
        self.revisions = revisions
 
348
 
 
349
 
 
350
class AmbiguousBase(BzrError):
 
351
    def __init__(self, bases):
 
352
        msg = "The correct base is unclear, becase %s are all equally close" %\
 
353
            ", ".join(bases)
 
354
        BzrError.__init__(self, msg)
 
355
        self.bases = bases
 
356
 
 
357
class NoCommits(BzrError):
 
358
    def __init__(self, branch):
 
359
        msg = "Branch %s has no commits." % branch
 
360
        BzrError.__init__(self, msg)
 
361
 
 
362
class UnlistableStore(BzrError):
 
363
    def __init__(self, store):
 
364
        BzrError.__init__(self, "Store %s is not listable" % store)
 
365
 
 
366
class UnlistableBranch(BzrError):
 
367
    def __init__(self, br):
 
368
        BzrError.__init__(self, "Stores for branch %s are not listable" % br)
 
369
 
 
370
 
 
371
class WeaveError(BzrNewError):
 
372
    """Error in processing weave: %(message)s"""
 
373
    def __init__(self, message=None):
 
374
        BzrNewError.__init__(self)
 
375
        self.message = message
 
376
 
 
377
 
 
378
class WeaveRevisionAlreadyPresent(WeaveError):
 
379
    """Revision {%(revision_id)s} already present in %(weave)s"""
 
380
    def __init__(self, revision_id, weave):
 
381
        WeaveError.__init__(self)
 
382
        self.revision_id = revision_id
 
383
        self.weave = weave
 
384
 
 
385
 
 
386
class WeaveRevisionNotPresent(WeaveError):
 
387
    """Revision {%(revision_id)s} not present in %(weave)s"""
 
388
    def __init__(self, revision_id, weave):
 
389
        WeaveError.__init__(self)
 
390
        self.revision_id = revision_id
 
391
        self.weave = weave
 
392
 
 
393
 
 
394
class WeaveFormatError(WeaveError):
 
395
    """Weave invariant violated: %(what)s"""
 
396
    def __init__(self, what):
 
397
        WeaveError.__init__(self)
 
398
        self.what = what
 
399
 
 
400
 
 
401
class WeaveParentMismatch(WeaveError):
 
402
    """Parents are mismatched between two revisions."""
 
403
    
 
404
 
 
405
class WeaveInvalidChecksum(WeaveError):
 
406
    """Text did not match it's checksum: %(message)s"""
 
407
 
 
408
 
 
409
class WeaveTextDiffers(WeaveError):
 
410
    """Weaves differ on text content. Revision: {%(revision_id)s}, %(weave_a)s, %(weave_b)s"""
 
411
 
 
412
    def __init__(self, revision_id, weave_a, weave_b):
 
413
        WeaveError.__init__(self)
 
414
        self.revision_id = revision_id
 
415
        self.weave_a = weave_a
 
416
        self.weave_b = weave_b
 
417
 
 
418
 
 
419
class NoSuchExportFormat(BzrNewError):
 
420
    """Export format %(format)r not supported"""
 
421
    def __init__(self, format):
 
422
        BzrNewError.__init__(self)
 
423
        self.format = format
 
424
 
 
425
 
 
426
class TransportError(BzrError):
 
427
    """All errors thrown by Transport implementations should derive
 
428
    from this class.
 
429
    """
 
430
    def __init__(self, msg=None, orig_error=None):
 
431
        if msg is None and orig_error is not None:
 
432
            msg = str(orig_error)
 
433
        BzrError.__init__(self, msg)
 
434
        self.msg = msg
 
435
        self.orig_error = orig_error
 
436
 
 
437
# A set of semi-meaningful errors which can be thrown
 
438
class TransportNotPossible(TransportError):
 
439
    """This is for transports where a specific function is explicitly not
 
440
    possible. Such as pushing files to an HTTP server.
 
441
    """
 
442
    pass
 
443
 
 
444
 
 
445
class ConnectionError(TransportError):
 
446
    """A connection problem prevents file retrieval.
 
447
    This does not indicate whether the file exists or not; it indicates that a
 
448
    precondition for requesting the file was not met.
 
449
    """
 
450
    def __init__(self, msg=None, orig_error=None):
 
451
        TransportError.__init__(self, msg=msg, orig_error=orig_error)
 
452
 
 
453
 
 
454
class ConnectionReset(TransportError):
 
455
    """The connection has been closed."""
 
456
    pass
 
457
 
 
458
class ConflictsInTree(BzrError):
 
459
    def __init__(self):
 
460
        BzrError.__init__(self, "Working tree has conflicts.")
 
461
 
 
462
class ParseConfigError(BzrError):
 
463
    def __init__(self, errors, filename):
 
464
        if filename is None:
 
465
            filename = ""
 
466
        message = "Error(s) parsing config file %s:\n%s" % \
 
467
            (filename, ('\n'.join(e.message for e in errors)))
 
468
        BzrError.__init__(self, message)
 
469
 
 
470
class SigningFailed(BzrError):
 
471
    def __init__(self, command_line):
 
472
        BzrError.__init__(self, "Failed to gpg sign data with command '%s'"
 
473
                               % command_line)
 
474
 
 
475
class WorkingTreeNotRevision(BzrError):
 
476
    def __init__(self, tree):
 
477
        BzrError.__init__(self, "The working tree for %s has changed since"
 
478
                          " last commit, but weave merge requires that it be"
 
479
                          " unchanged." % tree.basedir)
 
480
 
 
481
class CantReprocessAndShowBase(BzrNewError):
 
482
    """Can't reprocess and show base.
 
483
Reprocessing obscures relationship of conflicting lines to base."""
 
484
 
 
485
class GraphCycleError(BzrNewError):
 
486
    """Cycle in graph %(graph)r"""
 
487
    def __init__(self, graph):
 
488
        BzrNewError.__init__(self)
 
489
        self.graph = graph
 
490
 
 
491
 
 
492
class NotConflicted(BzrNewError):
 
493
    """File %(filename)s is not conflicted."""
 
494
 
 
495
    def __init__(self, filename):
 
496
        BzrNewError.__init__(self)
 
497
        self.filename = filename
 
498
 
 
499
 
 
500
class MustUseDecorated(Exception):
 
501
    """A decorating function has requested its original command be used.
 
502
    
 
503
    This should never escape bzr, so does not need to be printable.
 
504
    """
 
505
 
 
506
 
 
507
class MissingText(BzrNewError):
 
508
    """Branch %(base)s is missing revision %(text_revision)s of %(file_id)s"""
 
509
 
 
510
    def __init__(self, branch, text_revision, file_id):
 
511
        BzrNewError.__init__(self)
 
512
        self.branch = branch
 
513
        self.base = branch.base
 
514
        self.text_revision = text_revision
 
515
        self.file_id = file_id
 
516
 
 
517
 
 
518
class BzrBadParameter(BzrNewError):
 
519
    """A bad parameter : %(param)s is not usable.
 
520
    
 
521
    This exception should never be thrown, but it is a base class for all
 
522
    parameter-to-function errors.
 
523
    """
 
524
    def __init__(self, param):
 
525
        BzrNewError.__init__(self)
 
526
        self.param = param
 
527
 
 
528
 
 
529
class BzrBadParameterNotUnicode(BzrBadParameter):
 
530
    """Parameter %(param)s is neither unicode nor utf8."""
 
531
 
 
532
 
 
533
class BzrBadParameterNotString(BzrBadParameter):
 
534
    """Parameter %(param)s is not a string or unicode string."""
 
535
 
 
536
 
 
537
class BzrBadParameterMissing(BzrBadParameter):
 
538
    """Parameter $(param)s is required but not present."""
 
539
 
 
540
 
 
541
class DependencyNotPresent(BzrNewError):
 
542
    """Unable to import library: %(library)s, %(error)s"""
 
543
 
 
544
    def __init__(self, library, error):
 
545
        BzrNewError.__init__(self, library=library, error=error)
 
546
 
 
547
 
 
548
class ParamikoNotPresent(DependencyNotPresent):
 
549
    """Unable to import paramiko (required for sftp support): %(error)s"""
 
550
 
 
551
    def __init__(self, error):
 
552
        DependencyNotPresent.__init__(self, 'paramiko', error)
 
553
 
 
554
 
 
555
class UninitializableFormat(BzrNewError):
 
556
    """Format %(format)s cannot be initialised by this version of bzr."""
 
557
 
 
558
    def __init__(self, format):
 
559
        BzrNewError.__init__(self)
 
560
        self.format = format