~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/errors.py

  • Committer: Robert Collins
  • Date: 2005-10-18 13:11:57 UTC
  • mfrom: (1185.16.72) (0.2.1)
  • Revision ID: robertc@robertcollins.net-20051018131157-76a9970aa78e927e
Merged Martin.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
18
 
__copyright__ = "Copyright (C) 2005 Canonical Ltd."
19
 
__author__ = "Martin Pool <mbp@canonical.com>"
20
 
 
21
 
# TODO: Change to a standard exception pattern: 
22
 
#
23
 
# - docstring of exceptions is a template for formatting the exception
24
 
#   so the __str__ method can be defined only in the superclass
25
 
# - the arguments to the exception are interpolated into this string
26
 
#
27
 
# when printing the exception we'd then require special handling only
28
 
# for built-in exceptions with no decent __str__ method, such as 
29
 
# ValueError and AssertionError.  See 
30
 
# scott@canonical.com--2005/hct--devel--0.10 util/errors.py
31
 
 
32
 
 
33
 
######################################################################
34
 
# 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
...   print sys.exc_value.path
 
38
bzrlib.errors.NotBranchError
 
39
Not a branch: /foo/bar
 
40
/foo/bar
 
41
 
 
42
Therefore:
 
43
 
 
44
 * create a new exception class for any class of error that can be
 
45
   usefully distinguished.
 
46
 
 
47
 * the printable form of an exception is generated by the base class
 
48
   __str__ method
 
49
"""
 
50
 
 
51
# based on Scott James Remnant's hct error classes
 
52
 
 
53
# TODO: is there any value in providing the .args field used by standard
 
54
# python exceptions?   A list of values with no names seems less useful 
 
55
# to me.
 
56
 
 
57
# TODO: Perhaps convert the exception to a string at the moment it's 
 
58
# constructed to make sure it will succeed.  But that says nothing about
 
59
# exceptions that are never raised.
 
60
 
 
61
# TODO: Convert all the other error classes here to BzrNewError, and eliminate
 
62
# the old one.
 
63
 
 
64
 
35
65
class BzrError(StandardError):
36
66
    def __str__(self):
37
67
        # XXX: Should we show the exception class in 
51
81
            return n + `self.args`
52
82
 
53
83
 
54
 
class BzrCheckError(BzrError):
55
 
    pass
56
 
 
57
 
 
58
 
class InvalidRevisionNumber(BzrError):
 
84
class BzrNewError(BzrError):
 
85
    """bzr error"""
 
86
    # base classes should override the docstring with their human-
 
87
    # readable explanation
 
88
 
 
89
    def __init__(self, **kwds):
 
90
        for key, value in kwds.items():
 
91
            setattr(self, key, value)
 
92
 
59
93
    def __str__(self):
60
 
        return 'invalid revision number: %r' % self.args[0]
61
 
 
62
 
 
63
 
class InvalidRevisionId(BzrError):
64
 
    pass
 
94
        try:
 
95
            return self.__doc__ % self.__dict__
 
96
        except (NameError, ValueError, KeyError), e:
 
97
            return 'Unprintable exception %s: %s' \
 
98
                % (self.__class__.__name__, str(e))
 
99
 
 
100
 
 
101
class BzrCheckError(BzrNewError):
 
102
    """Internal check failed: %(message)s"""
 
103
    def __init__(self, message):
 
104
        self.message = message
 
105
 
 
106
 
 
107
class InvalidEntryName(BzrNewError):
 
108
    """Invalid entry name: %(name)s"""
 
109
    def __init__(self, name):
 
110
        self.name = name
 
111
 
 
112
 
 
113
class InvalidRevisionNumber(BzrNewError):
 
114
    """Invalid revision number %(revno)d"""
 
115
    def __init__(self, revno):
 
116
        self.revno = revno
 
117
 
 
118
 
 
119
class InvalidRevisionId(BzrNewError):
 
120
    """Invalid revision-id"""
65
121
 
66
122
 
67
123
class BzrCommandError(BzrError):
69
125
    def __str__(self):
70
126
        return self.args[0]
71
127
 
 
128
class StrictCommitFailed(Exception):
 
129
    """Commit refused because there are unknowns in the tree."""
72
130
 
73
 
class NotBranchError(BzrError):
74
 
    """Specified path is not in a branch"""
75
 
    def __str__(self):
76
 
        return 'not a branch: %s' % self.args[0]
 
131
class NotBranchError(BzrNewError):
 
132
    """Not a branch: %(path)s"""
 
133
    def __init__(self, path):
 
134
        BzrNewError.__init__(self)
 
135
        self.path = path
77
136
 
78
137
 
79
138
class UnsupportedFormatError(BzrError):
82
141
        return 'unsupported branch format: %s' % self.args[0]
83
142
 
84
143
 
85
 
class NotVersionedError(BzrError):
86
 
    """Specified object is not versioned."""
 
144
class NotVersionedError(BzrNewError):
 
145
    """%(path)s is not versioned"""
 
146
    def __init__(self, path):
 
147
        BzrNewError.__init__(self)
 
148
        self.path = path
87
149
 
88
150
 
89
151
class BadFileKindError(BzrError):
90
152
    """Specified file is of a kind that cannot be added.
91
153
 
92
154
    (For example a symlink or device file.)"""
93
 
    pass
94
155
 
95
156
 
96
157
class ForbiddenFileError(BzrError):
97
158
    """Cannot operate on a file because it is a control file."""
98
 
    pass
99
159
 
100
160
 
101
161
class LockError(Exception):
102
 
    """All exceptions from the lock/unlock functions should be from
103
 
    this exception class.  They will be translated as necessary. The
104
 
    original exception is available as e.original_error
105
 
    """
106
 
    def __init__(self, e=None):
107
 
        self.original_error = e
108
 
        if e:
109
 
            Exception.__init__(self, e)
110
 
        else:
111
 
            Exception.__init__(self)
 
162
    """Lock error"""
 
163
    # All exceptions from the lock/unlock functions should be from
 
164
    # this exception class.  They will be translated as necessary. The
 
165
    # original exception is available as e.original_error
112
166
 
113
167
 
114
168
class CommitNotPossible(LockError):
123
177
    """A write attempt was made in a read only transaction."""
124
178
 
125
179
 
126
 
class PointlessCommit(Exception):
127
 
    """Commit failed because nothing was changed."""
 
180
class PointlessCommit(BzrNewError):
 
181
    """No changes to commit"""
128
182
 
129
183
 
130
184
class NoSuchRevision(BzrError):