~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/errors.py

  • Committer: Robert Collins
  • Date: 2006-08-08 23:19:29 UTC
  • mfrom: (1884 +trunk)
  • mto: This revision was merged to the branch mainline in revision 1912.
  • Revision ID: robertc@robertcollins.net-20060808231929-4e3e298190214b3a
current status

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2005, 2006 Canonical
2
 
 
 
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
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
 
56
69
from warnings import warn
81
94
 
82
95
 
83
96
class BzrError(StandardError):
 
97
    
 
98
    is_user_error = True
 
99
    
84
100
    def __str__(self):
85
101
        # XXX: Should we show the exception class in 
86
102
        # exceptions that don't provide their own message?  
119
135
class BzrCheckError(BzrNewError):
120
136
    """Internal check failed: %(message)s"""
121
137
 
 
138
    is_user_error = False
 
139
 
122
140
    def __init__(self, message):
123
141
        BzrNewError.__init__(self)
124
142
        self.message = message
126
144
 
127
145
class InvalidEntryName(BzrNewError):
128
146
    """Invalid entry name: %(name)s"""
 
147
 
 
148
    is_user_error = False
 
149
 
129
150
    def __init__(self, name):
130
151
        BzrNewError.__init__(self)
131
152
        self.name = name
163
184
        self.url = url
164
185
 
165
186
 
166
 
class BzrCommandError(BzrError):
167
 
    # Error from malformed user command
168
 
    # This is being misused as a generic exception
169
 
    # pleae subclass. RBC 20051030
 
187
class BzrCommandError(BzrNewError):
 
188
    """Error from user command"""
 
189
 
 
190
    is_user_error = True
 
191
 
 
192
    # Error from malformed user command; please avoid raising this as a
 
193
    # generic exception not caused by user input.
170
194
    #
171
195
    # I think it's a waste of effort to differentiate between errors that
172
196
    # are not intended to be caught anyway.  UI code need not subclass
173
197
    # BzrCommandError, and non-UI code should not throw a subclass of
174
198
    # BzrCommandError.  ADHB 20051211
 
199
    def __init__(self, msg):
 
200
        self.msg = msg
 
201
 
175
202
    def __str__(self):
176
 
        return self.args[0]
 
203
        return self.msg
177
204
 
178
205
 
179
206
class BzrOptionError(BzrCommandError):
180
 
    """Some missing or otherwise incorrect option was supplied."""
 
207
    """Error in command line options"""
181
208
 
182
209
    
183
 
class StrictCommitFailed(Exception):
184
 
    """Commit refused because there are unknowns in the tree."""
 
210
class StrictCommitFailed(BzrNewError):
 
211
    """Commit refused because there are unknown files in the tree"""
185
212
 
186
213
 
187
214
# XXX: Should be unified with TransportError; they seem to represent the
231
258
        self.args.extend(args)
232
259
 
233
260
 
 
261
class UnsupportedProtocol(PathError):
 
262
    """Unsupported protocol for url "%(path)s"%(extra)s"""
 
263
 
 
264
    def __init__(self, url, extra):
 
265
        PathError.__init__(self, url, extra=extra)
 
266
 
 
267
 
234
268
class PathNotChild(BzrNewError):
235
269
    """Path %(path)r is not a child of path %(base)r%(extra)s"""
 
270
 
 
271
    is_user_error = False
 
272
 
236
273
    def __init__(self, path, base, extra=None):
237
274
        BzrNewError.__init__(self)
238
275
        self.path = path
243
280
            self.extra = ''
244
281
 
245
282
 
 
283
class InvalidNormalization(PathError):
 
284
    """Path %(path)r is not unicode normalized"""
 
285
 
 
286
 
246
287
# TODO: This is given a URL; we try to unescape it but doing that from inside
247
288
# the exception object is a bit undesirable.
248
289
# TODO: Probably this behavior of should be a common superclass 
280
321
        self.path = path
281
322
 
282
323
 
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]
 
324
class UnsupportedFormatError(BzrNewError):
 
325
    """Unsupported branch format: %(format)s"""
 
326
 
 
327
 
 
328
class UnknownFormatError(BzrNewError):
 
329
    """Unknown branch format: %(format)r"""
293
330
 
294
331
 
295
332
class IncompatibleFormat(BzrNewError):
333
370
        self.paths_as_string = ' '.join([quotefn(p) for p in paths])
334
371
 
335
372
 
336
 
class BadFileKindError(BzrError):
337
 
    """Specified file is of a kind that cannot be added.
338
 
 
339
 
    (For example a symlink or device file.)"""
340
 
 
341
 
 
342
 
class ForbiddenFileError(BzrError):
343
 
    """Cannot operate on a file because it is a control file."""
 
373
class BadFileKindError(BzrNewError):
 
374
    """Cannot operate on %(filename)s of unsupported kind %(kind)s"""
 
375
 
 
376
 
 
377
class ForbiddenControlFileError(BzrNewError):
 
378
    """Cannot operate on %(filename)s because it is a control file"""
344
379
 
345
380
 
346
381
class LockError(BzrNewError):
378
413
 
379
414
class ObjectNotLocked(LockError):
380
415
    """%(obj)r is not locked"""
 
416
 
 
417
    is_user_error = False
 
418
 
381
419
    # this can indicate that any particular object is not locked; see also
382
420
    # LockNotHeld which means that a particular *lock* object is not held by
383
421
    # the caller -- perhaps they should be unified.
445
483
    """Commit refused because there are unknowns in the tree."""
446
484
 
447
485
 
448
 
class NoSuchRevision(BzrError):
 
486
class NoSuchRevision(BzrNewError):
 
487
    """Branch %(branch)s has no revision %(revision)s"""
 
488
 
 
489
    is_user_error = False
 
490
 
449
491
    def __init__(self, branch, revision):
450
492
        self.branch = branch
451
493
        self.revision = revision
452
 
        msg = "Branch %s has no revision %s" % (branch, revision)
453
 
        BzrError.__init__(self, msg)
454
494
 
455
495
 
456
496
class HistoryMissing(BzrError):
461
501
                          % (branch, object_type, object_id))
462
502
 
463
503
 
464
 
class DivergedBranches(BzrError):
 
504
class DivergedBranches(BzrNewError):
 
505
    "These branches have diverged.  Use the merge command to reconcile them."""
 
506
 
 
507
    is_user_error = True
465
508
 
466
509
    def __init__(self, branch1, branch2):
467
 
        BzrError.__init__(self, "These branches have diverged.  Try merge.")
468
510
        self.branch1 = branch1
469
511
        self.branch2 = branch2
470
512
 
471
513
 
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):
 
514
class UnrelatedBranches(BzrNewError):
 
515
    "Branches have no common ancestor, and no merge base revision was specified."
 
516
 
 
517
    is_user_error = True
 
518
 
 
519
 
 
520
class NoCommonAncestor(BzrNewError):
 
521
    "Revisions have no common ancestor: %(revision_a)s %(revision_b)s"
 
522
 
480
523
    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)
 
524
        self.revision_a = revision_a
 
525
        self.revision_b = revision_b
484
526
 
485
527
 
486
528
class NoCommonRoot(BzrError):
511
553
    def __init__(self, bases):
512
554
        warn("BzrError AmbiguousBase has been deprecated as of bzrlib 0.8.",
513
555
                DeprecationWarning)
514
 
        msg = "The correct base is unclear, becase %s are all equally close" %\
 
556
        msg = "The correct base is unclear, because %s are all equally close" %\
515
557
            ", ".join(bases)
516
558
        BzrError.__init__(self, msg)
517
559
        self.bases = bases
679
721
        self.format = format
680
722
 
681
723
 
682
 
class TransportError(BzrError):
683
 
    """All errors thrown by Transport implementations should derive
684
 
    from this class.
685
 
    """
 
724
class TransportError(BzrNewError):
 
725
    """Transport error: %(msg)s %(orig_error)s"""
 
726
 
686
727
    def __init__(self, msg=None, orig_error=None):
687
728
        if msg is None and orig_error is not None:
688
729
            msg = str(orig_error)
689
 
        BzrError.__init__(self, msg)
 
730
        if orig_error is None:
 
731
            orig_error = ''
 
732
        if msg is None:
 
733
            msg =  ''
690
734
        self.msg = msg
691
735
        self.orig_error = orig_error
 
736
        BzrNewError.__init__(self)
692
737
 
693
738
 
694
739
# A set of semi-meaningful errors which can be thrown
695
740
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
 
741
    """Transport operation not possible: %(msg)s %(orig_error)%"""
700
742
 
701
743
 
702
744
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)
 
745
    """Connection error: %(msg)s %(orig_error)s"""
709
746
 
710
747
 
711
748
class ConnectionReset(TransportError):
712
 
    """The connection has been closed."""
713
 
    pass
 
749
    """Connection closed: %(msg)s %(orig_error)s"""
 
750
 
 
751
 
 
752
class InvalidRange(TransportError):
 
753
    """Invalid range access."""
 
754
    
 
755
    def __init__(self, path, offset):
 
756
        TransportError.__init__(self, ("Invalid range access in %s at %d"
 
757
                                       % (path, offset)))
 
758
 
 
759
 
 
760
class InvalidHttpResponse(TransportError):
 
761
    """Invalid http response for %(path)s: %(msg)s"""
 
762
 
 
763
    def __init__(self, path, msg, orig_error=None):
 
764
        self.path = path
 
765
        TransportError.__init__(self, msg, orig_error=orig_error)
 
766
 
 
767
 
 
768
class InvalidHttpRange(InvalidHttpResponse):
 
769
    """Invalid http range "%(range)s" for %(path)s: %(msg)s"""
 
770
    
 
771
    def __init__(self, path, range, msg):
 
772
        self.range = range
 
773
        InvalidHttpResponse.__init__(self, path, msg)
 
774
 
 
775
 
 
776
class InvalidHttpContentType(InvalidHttpResponse):
 
777
    """Invalid http Content-type "%(ctype)s" for %(path)s: %(msg)s"""
 
778
    
 
779
    def __init__(self, path, ctype, msg):
 
780
        self.ctype = ctype
 
781
        InvalidHttpResponse.__init__(self, path, msg)
714
782
 
715
783
 
716
784
class ConflictsInTree(BzrError):
862
930
        self.format = format
863
931
 
864
932
 
 
933
class NoDiff(BzrNewError):
 
934
    """Diff is not installed on this machine: %(msg)s"""
 
935
 
 
936
    def __init__(self, msg):
 
937
        super(NoDiff, self).__init__(msg=msg)
 
938
 
 
939
 
865
940
class NoDiff3(BzrNewError):
866
941
    """Diff3 is not installed on this machine."""
867
942
 
927
1002
    """A nested progress bar was not 'finished' correctly."""
928
1003
 
929
1004
 
 
1005
class InvalidProgressBarType(BzrNewError):
 
1006
    """Environment variable BZR_PROGRESS_BAR='%(bar_type)s is not a supported type
 
1007
Select one of: %(valid_types)s"""
 
1008
 
 
1009
    def __init__(self, bar_type, valid_types):
 
1010
        BzrNewError.__init__(self, bar_type=bar_type, valid_types=valid_types)
 
1011
 
 
1012
 
930
1013
class UnsupportedOperation(BzrNewError):
931
1014
    """The method %(mname)s is not supported on objects of type %(tname)s."""
932
1015
    def __init__(self, method, method_self):