Merge 0.4.
[jelmer/subvertpy.git] / errors.py
1 # Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
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 """Subversion-specific errors and conversion of Subversion-specific errors."""
17
18 from bzrlib.errors import (BzrError, ConnectionError, ConnectionReset, 
19                            LockError, NotBranchError, PermissionDenied, 
20                            DependencyNotPresent, NoRepositoryPresent,
21                            TransportError, UnexpectedEndOfContainerError)
22
23 import urllib
24 import svn.core
25
26 # APR define, not in svn.core
27 SVN_ERR_UNKNOWN_HOSTNAME = 670002
28
29 class NotSvnBranchPath(NotBranchError):
30     """Error raised when a path was specified that did not exist."""
31     _fmt = """%(path)s is not a valid Subversion branch path. 
32 See 'bzr help svn-branching-schemes' for details."""
33
34     def __init__(self, branch_path, scheme=None):
35         NotBranchError.__init__(self, urllib.quote(branch_path))
36         self.scheme = scheme
37
38
39 class InvalidSvnBranchPath(NotBranchError):
40     """Error raised when a path was specified that is not a child of or itself
41     a valid branch path in the current branching scheme."""
42     _fmt = """%(path)s is not a valid Subversion branch path in the current 
43 branching scheme. See 'bzr help svn-branching schemes' for details."""
44
45     def __init__(self, path, scheme):
46         assert isinstance(path, str)
47         NotBranchError.__init__(self, urllib.quote(path))
48         self.scheme = scheme
49
50
51 class NoSvnRepositoryPresent(NoRepositoryPresent):
52
53     def __init__(self, url):
54         BzrError.__init__(self)
55         self.path = url
56
57
58 class ChangesRootLHSHistory(BzrError):
59     _fmt = """changing lhs branch history not possible on repository root"""
60
61
62 class MissingPrefix(BzrError):
63     _fmt = """Prefix missing for %(path)s; please create it before pushing. """
64
65     def __init__(self, path):
66         BzrError.__init__(self)
67         self.path = path
68
69
70 class RevpropChangeFailed(BzrError):
71     _fmt = """Unable to set revision property %(name)s."""
72
73     def __init__(self, name):
74         BzrError.__init__(self)
75         self.name = name
76
77
78 def convert_error(err):
79     """Convert a Subversion exception to the matching BzrError.
80
81     :param err: SubversionException.
82     :return: BzrError instance if it could be converted, err otherwise
83     """
84     (msg, num) = err.args
85
86     if num == svn.core.SVN_ERR_RA_SVN_CONNECTION_CLOSED:
87         return ConnectionReset(msg=msg)
88     elif num == svn.core.SVN_ERR_WC_LOCKED:
89         return LockError(message=msg)
90     elif num == svn.core.SVN_ERR_RA_NOT_AUTHORIZED:
91         return PermissionDenied('.', msg)
92     elif num == svn.core.SVN_ERR_INCOMPLETE_DATA:
93         return UnexpectedEndOfContainerError()
94     elif num == svn.core.SVN_ERR_RA_SVN_MALFORMED_DATA:
95         return TransportError("Malformed data", msg)
96     elif num == svn.core.SVN_ERR_RA_NOT_IMPLEMENTED:
97         return NotImplementedError("Function not implemented in remote server")
98     elif num == SVN_ERR_UNKNOWN_HOSTNAME:
99         return ConnectionError(msg=msg)
100     elif num > 0 and num < 1000:
101         return OSError(num, msg)
102     else:
103         return err
104
105
106 def convert_svn_error(unbound):
107     """Decorator that catches particular Subversion exceptions and 
108     converts them to Bazaar exceptions.
109     """
110     def convert(*args, **kwargs):
111         try:
112             return unbound(*args, **kwargs)
113         except svn.core.SubversionException, e:
114             raise convert_error(e)
115
116     convert.__doc__ = unbound.__doc__
117     convert.__name__ = unbound.__name__
118     return convert
119
120
121 class NoCheckoutSupport(BzrError):
122
123     _fmt = 'Subversion version too old for working tree support.'
124
125
126 class LocalCommitsUnsupported(BzrError):
127
128     _fmt = 'Local commits are not supported for lightweight Subversion checkouts.'
129
130
131 class InvalidPropertyValue(BzrError):
132     _fmt = 'Invalid property value for Subversion property %(property)s: %(msg)s'
133
134     def __init__(self, property, msg):
135         BzrError.__init__(self)
136         self.property = property
137         self.msg = msg
138
139 class RebaseNotPresent(DependencyNotPresent):
140     _fmt = "Unable to import bzr-rebase (required for svn-upgrade support): %(error)s"
141
142     def __init__(self, error):
143         DependencyNotPresent.__init__(self, 'bzr-rebase', error)
144
145
146 class InvalidFileName(BzrError):
147     _fmt = "Unable to convert Subversion path %(path)s because it contains characters invalid in Bazaar."
148
149     def __init__(self, path):
150         BzrError.__init__(self)
151         self.path = path
152
153
154 class CorruptMappingData(BzrError):
155     _fmt = """An invalid change was made to the bzr-specific properties in %(path)s."""
156
157     def __init__(self, path):
158         BzrError.__init__(self)
159         self.path = path