Merge lp:~nataliabidart/ubuntuone-storage-protocol/map-those-errors into lp:ubuntuone-storage-protocol

Proposed by Natalia Bidart
Status: Merged
Approved by: John O'Brien
Approved revision: 98
Merged at revision: not available
Proposed branch: lp:~nataliabidart/ubuntuone-storage-protocol/map-those-errors
Merge into: lp:ubuntuone-storage-protocol
Diff against target: 632 lines (+309/-74)
9 files modified
pylintrc (+3/-1)
tests/test_client.py (+1/-1)
tests/test_errors.py (+51/-0)
tests/test_request.py (+59/-6)
tests/test_volumes.py (+1/-1)
ubuntuone/storageprotocol/client.py (+22/-30)
ubuntuone/storageprotocol/errors.py (+156/-0)
ubuntuone/storageprotocol/request.py (+14/-35)
ubuntuone/storageprotocol/volumes.py (+2/-0)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-storage-protocol/map-those-errors
Reviewer Review Type Date Requested Status
John O'Brien (community) Approve
dobey (community) Approve
Review via email: mp+22640@code.launchpad.net

Commit message

Added an internal mapping to correctly raise specific exceptions when an ERROR was received in a Request.

Description of the change

Added an internal mapping to correctly raise specific exceptions when an ERROR was received in a Request.

To post a comment you must log in.
Revision history for this message
dobey (dobey) wrote :

Can you clarify the pylintrc change by also adding comments as per the other values for disable-msg= above the disable-msg= line, or revert the change, using localized disable-msg comments instead if necessary? I'd like to avoid globally disabling messages when possible, as doing so may mask warnings that we should fix.

And can you use the following coding annotation instead, so that it's handled better by different editors?
# -*- coding: utf-8 -*-

review: Needs Fixing
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

> Can you clarify the pylintrc change by also adding comments as per the other
> values for disable-msg= above the disable-msg= line, or revert the change,
> using localized disable-msg comments instead if necessary? I'd like to avoid
> globally disabling messages when possible, as doing so may mask warnings that
> we should fix.
>
> And can you use the following coding annotation instead, so that it's handled
> better by different editors?
> # -*- coding: utf-8 -*-

All changes added in revision 98.

98. By Natalia Bidart

Adding details to pylint disable-msg. Unified coding defs.

Revision history for this message
dobey (dobey) :
review: Approve
Revision history for this message
John O'Brien (jdobrien) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'pylintrc'
--- pylintrc 2009-03-26 15:47:10 +0000
+++ pylintrc 2010-04-01 18:11:31 +0000
@@ -24,7 +24,9 @@
24# :W0613: *Unused argument %r* (We get lots of these from interfaces)24# :W0613: *Unused argument %r* (We get lots of these from interfaces)
25# :W0621: *Redefining name %r from outer scope (line %s)* (pylint does a poor evaluation)25# :W0621: *Redefining name %r from outer scope (line %s)* (pylint does a poor evaluation)
26# :W0622: *Redefining built-in '%r'26# :W0622: *Redefining built-in '%r'
27disable-msg=E0101,W0142,W0221,W0613,W0621,W062227# :W0201: *Attribute '%r' defined outside __init__*
28# :W0212: *Access to a protected member %r of a client class*
29disable-msg=E0101,W0142,W0221,W0613,W0621,W0622,W0201,W0212
2830
2931
30[REPORTS]32[REPORTS]
3133
=== modified file 'tests/test_client.py'
--- tests/test_client.py 2010-01-04 18:21:24 +0000
+++ tests/test_client.py 2010-04-01 18:11:31 +0000
@@ -1,4 +1,4 @@
1# coding=utf-81# -*- coding: utf-8 -*-
2#2#
3# Author: Natalia B. Bidart <natalia.bidart@canonical.com>3# Author: Natalia B. Bidart <natalia.bidart@canonical.com>
4#4#
55
=== added file 'tests/test_errors.py'
--- tests/test_errors.py 1970-01-01 00:00:00 +0000
+++ tests/test_errors.py 2010-04-01 18:11:31 +0000
@@ -0,0 +1,51 @@
1# -*- coding: utf-8 -*-
2#
3# Author: Natalia B. Bidart <natalia.bidart@canonical.com>
4#
5# Copyright (C) 2010 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU Affero General Public License version 3,
9# as published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU Affero General Public License for more details.
15#
16# You should have received a copy of the GNU Affero General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18"""Tests for errors module."""
19
20import unittest
21
22from ubuntuone.storageprotocol import errors, protocol_pb2
23
24REQ_ARGS = dict(request=None, message=protocol_pb2.Message())
25
26HIGH_LEVEL_ERRORS = {errors.StorageProtocolErrorSizeTooBig: dict(),
27 errors.StorageProtocolProtocolError: dict(),
28 errors.StorageRequestError: REQ_ARGS,
29 errors.RequestCancelledError: dict()}
30
31
32class ErrorsTestCase(unittest.TestCase):
33 """Basic testing of errors mapping."""
34
35 def setUp(self):
36 """Init."""
37
38 def test_exceptions_are_storage_protocol_error(self):
39 """High level exceptions inherit from StorageProtocolError."""
40 for e, args in HIGH_LEVEL_ERRORS.iteritems():
41 self.assertTrue(isinstance(e(**args), errors.StorageProtocolError),
42 "%r must inherit from StorageProtocolError" % e)
43
44 def test_mapping(self):
45 """Protocol's specific exceptions are correct."""
46 for code_error, proto_error in errors._error_mapping.iteritems():
47 self.assertTrue(isinstance(proto_error(**REQ_ARGS),
48 errors.StorageRequestError),
49 "%r must inherit from StorageRequestError" %
50 proto_error)
51 self.assertEqual(proto_error, errors.error_to_exception(code_error))
052
=== modified file 'tests/test_request.py'
--- tests/test_request.py 2009-06-26 16:23:19 +0000
+++ tests/test_request.py 2010-04-01 18:11:31 +0000
@@ -2,16 +2,17 @@
2# request class tests2# request class tests
3#3#
4# Author: Tim Cole <tim.cole@canonical.com>4# Author: Tim Cole <tim.cole@canonical.com>
5# Author: Natalia Bidart <natalia.bidart@canonical.com>
5#6#
6# Copyright (C) 2009 Canonical7# Copyright (C) 2009 Canonical
7#8#
8# This program is free software: you can redistribute it and/or modify it 9# This program is free software: you can redistribute it and/or modify it
9# under the terms of the GNU Affero General Public License version 3,10# under the terms of the GNU Affero General Public License version 3,
10# as published by the Free Software Foundation.11# as published by the Free Software Foundation.
11#12#
12# This program is distributed in the hope that it will be useful, but 13# This program is distributed in the hope that it will be useful, but
13# WITHOUT ANY WARRANTY; without even the implied warranties of 14# WITHOUT ANY WARRANTY; without even the implied warranties of
14# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 15# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15# PURPOSE. See the GNU Affero General Public License for more details.16# PURPOSE. See the GNU Affero General Public License for more details.
16#17#
17# You should have received a copy of the GNU Affero General Public License18# You should have received a copy of the GNU Affero General Public License
@@ -20,9 +21,13 @@
2021
21from __future__ import with_statement22from __future__ import with_statement
2223
23from twisted.trial.unittest import TestCase24import unittest
25
26from twisted.trial.unittest import TestCase as TwistedTestCase
24from twisted.internet.defer import inlineCallbacks27from twisted.internet.defer import inlineCallbacks
25from twisted.python.failure import Failure28from twisted.python.failure import Failure
29
30from ubuntuone.storageprotocol import errors, protocol_pb2
26from ubuntuone.storageprotocol.request import (31from ubuntuone.storageprotocol.request import (
27 RequestHandler, Request)32 RequestHandler, Request)
2833
@@ -50,7 +55,7 @@
50 self.producer = None55 self.producer = None
5156
5257
53class TestRequests(TestCase):58class TestRequests(TwistedTestCase):
54 """Tests for request handling."""59 """Tests for request handling."""
5560
56 @inlineCallbacks61 @inlineCallbacks
@@ -74,3 +79,51 @@
74 pass # passed79 pass # passed
75 else:80 else:
76 self.fail("Expected to fail with the correct reason.")81 self.fail("Expected to fail with the correct reason.")
82
83
84class TestRequest(unittest.TestCase):
85 """Tests for request object."""
86
87 def setUp(self):
88 """Init."""
89 self.request = MindlessRequest(protocol=None)
90 self.error = None
91 self.request.error = lambda error: setattr(self, 'error', error)
92
93 def tearDown(self):
94 """Clean up."""
95 self.error = None
96 self.request = None
97
98 def test_default_process_message_basic(self):
99 """_default_process_message maps errors to exceptions."""
100 message = protocol_pb2.Message()
101 self.request._default_process_message(message)
102
103 self.assertTrue(isinstance(self.error, errors.StorageRequestError))
104 self.assertEqual(self.request, self.error.request)
105 self.assertEqual(message, self.error.error_message)
106
107 def test_default_process_message_no_error_message(self):
108 """_default_process_message maps errors to exceptions."""
109 message = protocol_pb2.Message()
110 self.request._default_process_message(message)
111
112 self.assertTrue(self.error.__class__ is errors.StorageRequestError)
113 self.assertEqual(self.request, self.error.request)
114 self.assertEqual(message, self.error.error_message)
115
116 def test_default_process_message(self):
117 """_default_process_message maps errors to exceptions."""
118 for code_error, proto_error in errors._error_mapping.iteritems():
119 message = protocol_pb2.Message()
120 message.type = protocol_pb2.Message.ERROR
121 message.error.type = code_error
122 self.request._default_process_message(message)
123
124 self.assertTrue(isinstance(self.error, proto_error),
125 "must be an instance of %r" % proto_error)
126 self.assertEqual(self.request, self.error.request)
127 self.assertEqual(message, self.error.error_message)
128
129 self.error = None
77130
=== modified file 'tests/test_volumes.py'
--- tests/test_volumes.py 2009-12-23 16:29:02 +0000
+++ tests/test_volumes.py 2010-04-01 18:11:31 +0000
@@ -1,4 +1,4 @@
1# coding=utf-81# -*- coding: utf-8 -*-
2#2#
3# Author: Natalia B. Bidart <natalia.bidart@canonical.com>3# Author: Natalia B. Bidart <natalia.bidart@canonical.com>
4#4#
55
=== modified file 'ubuntuone/storageprotocol/client.py'
--- ubuntuone/storageprotocol/client.py 2010-03-12 20:32:23 +0000
+++ ubuntuone/storageprotocol/client.py 2010-04-01 18:11:31 +0000
@@ -569,14 +569,12 @@
569 if self.callback is None:569 if self.callback is None:
570 self.data = "".join(self.parts)570 self.data = "".join(self.parts)
571 self.done()571 self.done()
572 elif message.type == protocol_pb2.Message.ERROR:
573 self.error(request.StorageRequestError(self, message))
574 elif message.type == protocol_pb2.Message.OK:572 elif message.type == protocol_pb2.Message.OK:
575 self.done()573 self.done()
576 elif message.type == protocol_pb2.Message.CANCELLED:574 elif message.type == protocol_pb2.Message.CANCELLED:
577 self.error(request.RequestCancelledError("CANCELLED"))575 self.error(request.RequestCancelledError("CANCELLED"))
578 else:576 else:
579 self.error(request.StorageProtocolProtocolError(message))577 self._default_process_message(message)
580578
581 def _cancel(self):579 def _cancel(self):
582 """Cancel the current download."""580 """Cancel the current download."""
@@ -609,7 +607,7 @@
609 elif message.type == protocol_pb2.Message.SHARES_END:607 elif message.type == protocol_pb2.Message.SHARES_END:
610 self.done()608 self.done()
611 else:609 else:
612 self.error(request.StorageRequestError(self, message))610 self._default_process_message(message)
613611
614612
615class CreateShare(request.Request):613class CreateShare(request.Request):
@@ -666,7 +664,7 @@
666 # XXX: this is for PROTOCOL_VERSION=1 backward compatibility664 # XXX: this is for PROTOCOL_VERSION=1 backward compatibility
667 self.done()665 self.done()
668 else:666 else:
669 self.error(request.StorageRequestError(self, message))667 self._default_process_message(message)
670668
671669
672class AcceptShare(request.Request):670class AcceptShare(request.Request):
@@ -711,7 +709,7 @@
711 if message.type == protocol_pb2.Message.OK:709 if message.type == protocol_pb2.Message.OK:
712 self.done()710 self.done()
713 else:711 else:
714 self.error(request.StorageRequestError(self, message))712 self._default_process_message(message)
715713
716714
717class DeleteShare(request.Request):715class DeleteShare(request.Request):
@@ -739,7 +737,7 @@
739 if message.type == protocol_pb2.Message.OK:737 if message.type == protocol_pb2.Message.OK:
740 self.done()738 self.done()
741 else:739 else:
742 self.error(request.StorageRequestError(self, message))740 self._default_process_message(message)
743741
744742
745class CreateUDF(request.Request):743class CreateUDF(request.Request):
@@ -774,7 +772,7 @@
774 self.node_id = message.volume_created.udf.node772 self.node_id = message.volume_created.udf.node
775 self.done()773 self.done()
776 else:774 else:
777 self.error(request.StorageRequestError(self, message))775 self._default_process_message(message)
778776
779777
780class ListVolumes(request.Request):778class ListVolumes(request.Request):
@@ -816,7 +814,7 @@
816 elif message.type == protocol_pb2.Message.VOLUMES_END:814 elif message.type == protocol_pb2.Message.VOLUMES_END:
817 self.done()815 self.done()
818 else:816 else:
819 self.error(request.StorageRequestError(self, message))817 self._default_process_message(message)
820818
821819
822class DeleteVolume(request.Request):820class DeleteVolume(request.Request):
@@ -844,7 +842,7 @@
844 if message.type == protocol_pb2.Message.OK:842 if message.type == protocol_pb2.Message.OK:
845 self.done()843 self.done()
846 else:844 else:
847 self.error(request.StorageRequestError(self, message))845 self._default_process_message(message)
848846
849847
850class Unlink(request.Request):848class Unlink(request.Request):
@@ -875,7 +873,7 @@
875 if message.type == protocol_pb2.Message.OK:873 if message.type == protocol_pb2.Message.OK:
876 self.done()874 self.done()
877 else:875 else:
878 self.error(request.StorageRequestError(self, message))876 self._default_process_message(message)
879877
880878
881class Move(request.Request):879class Move(request.Request):
@@ -914,10 +912,8 @@
914 if message.type == protocol_pb2.Message.OK:912 if message.type == protocol_pb2.Message.OK:
915 self.done()913 self.done()
916 else:914 else:
917 # XXX:915 self._default_process_message(message)
918 # lucio.torre916
919 # handle more error messages
920 self.error(request.StorageRequestError(self, message))
921917
922class MultiQuery(object):918class MultiQuery(object):
923 """Create a Request-like object that encapsulates many Query requests919 """Create a Request-like object that encapsulates many Query requests
@@ -954,6 +950,7 @@
954 for q in self.queries:950 for q in self.queries:
955 q.start()951 q.start()
956952
953
957class Query(request.Request):954class Query(request.Request):
958 """Query about the hash of a node_id.955 """Query about the hash of a node_id.
959956
@@ -1011,10 +1008,7 @@
1011 elif message.type == protocol_pb2.Message.QUERY_END:1008 elif message.type == protocol_pb2.Message.QUERY_END:
1012 self.done()1009 self.done()
1013 else:1010 else:
1014 # XXX:1011 self._default_process_message(message)
1015 # lucio.torre
1016 # handle more error messages
1017 self.error(message)
10181012
10191013
1020class BytesMessageProducer(object):1014class BytesMessageProducer(object):
@@ -1122,7 +1116,7 @@
1122 elif message.type == protocol_pb2.Message.CANCELLED:1116 elif message.type == protocol_pb2.Message.CANCELLED:
1123 self.error(request.RequestCancelledError("CANCELLED"))1117 self.error(request.RequestCancelledError("CANCELLED"))
1124 else:1118 else:
1125 self.error(request.StorageRequestError(self, message))1119 self._default_process_message(message)
11261120
1127 def _cancel(self):1121 def _cancel(self):
1128 """Cancel the current upload."""1122 """Cancel the current upload."""
@@ -1183,7 +1177,8 @@
1183 self.new_name = message.new.name1177 self.new_name = message.new.name
1184 self.done()1178 self.done()
1185 else:1179 else:
1186 self.error(request.StorageRequestError(self, message))1180 self._default_process_message(message)
1181
11871182
1188class MakeDir(MakeObject):1183class MakeDir(MakeObject):
1189 """Extend MakeObject to make directories."""1184 """Extend MakeObject to make directories."""
@@ -1224,7 +1219,8 @@
1224 self.other_protocol_version = message.protocol.version1219 self.other_protocol_version = message.protocol.version
1225 self.done()1220 self.done()
1226 else:1221 else:
1227 self.error(request.StorageRequestError(self, message))1222 self._default_process_message(message)
1223
12281224
1229class Authenticate(request.Request):1225class Authenticate(request.Request):
1230 """Request to authenticate the user."""1226 """Request to authenticate the user."""
@@ -1253,12 +1249,8 @@
1253 """Handle messages."""1249 """Handle messages."""
1254 if message.type == protocol_pb2.Message.AUTH_AUTHENTICATED:1250 if message.type == protocol_pb2.Message.AUTH_AUTHENTICATED:
1255 self.done()1251 self.done()
1256 elif message.type == protocol_pb2.Message.ERROR:
1257 # as the error travels with the exception, we send all here
1258 self.error(request.StorageRequestError(self, message))
1259 else:1252 else:
1260 self.error(request.StorageProtocolError(1253 self._default_process_message(message)
1261 "Authentication Error:"+str(message)))
12621254
12631255
1264class QuerySetCaps(request.Request):1256class QuerySetCaps(request.Request):
@@ -1304,7 +1296,7 @@
1304 self.redirect_srvrecord = message.accept_caps.redirect_srvrecord1296 self.redirect_srvrecord = message.accept_caps.redirect_srvrecord
1305 self.done()1297 self.done()
1306 else:1298 else:
1307 self.error(request.StorageRequestError(self, message))1299 self._default_process_message(message)
13081300
13091301
1310class FreeSpaceInquiry(request.Request):1302class FreeSpaceInquiry(request.Request):
@@ -1330,7 +1322,7 @@
1330 self.free_bytes = message.free_space_info.free_bytes1322 self.free_bytes = message.free_space_info.free_bytes
1331 self.done()1323 self.done()
1332 else:1324 else:
1333 self.error(request.StorageRequestError(self, message))1325 self._default_process_message(message)
13341326
13351327
1336class AccountInquiry(request.Request):1328class AccountInquiry(request.Request):
@@ -1350,7 +1342,7 @@
1350 self.purchased_bytes = message.account_info.purchased_bytes1342 self.purchased_bytes = message.account_info.purchased_bytes
1351 self.done()1343 self.done()
1352 else:1344 else:
1353 self.error(request.StorageRequestError(self, message))1345 self._default_process_message(message)
13541346
13551347
1356class ThrottlingStorageClient(StorageClient):1348class ThrottlingStorageClient(StorageClient):
13571349
=== added file 'ubuntuone/storageprotocol/errors.py'
--- ubuntuone/storageprotocol/errors.py 1970-01-01 00:00:00 +0000
+++ ubuntuone/storageprotocol/errors.py 2010-04-01 18:11:31 +0000
@@ -0,0 +1,156 @@
1# -*- coding: utf-8 -*-
2#
3# Author: Natalia B. Bidart <natalia.bidart@canonical.com>
4#
5# Copyright 2010 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU Affero General Public License version 3,
9# as published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU Affero General Public License for more details.
15#
16# You should have received a copy of the GNU Affero General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18"""The errors abstraction."""
19
20from ubuntuone.storageprotocol import protocol_pb2
21
22
23class StorageProtocolError(Exception):
24 """Base class for all client/server exceptions."""
25
26
27class StorageProtocolErrorSizeTooBig(StorageProtocolError):
28 """The size we received was too big."""
29
30
31class StorageProtocolProtocolError(StorageProtocolError):
32 """A protocol error on the storage protocol."""
33
34
35class StorageRequestError(StorageProtocolError):
36 """An exception that keeps the request that generated it around."""
37
38 def __init__(self, request, message):
39 """Create a StorageRequestError.
40
41 @param request: the request that generated this error.
42 @param message: the message received that generated the error.
43 """
44 error_name = protocol_pb2.Error.DESCRIPTOR \
45 .enum_types_by_name['ErrorType'] \
46 .values_by_number[message.error.type].name
47 super(StorageRequestError, self).__init__(error_name)
48 #: the request that generated the error
49 self.request = request
50 #: the message received that generated the error
51 self.error_message = message
52
53
54class RequestCancelledError(StorageProtocolError):
55 """The request was cancelled."""
56
57
58# Request specific errors
59
60
61class UnsupportedVersionError(StorageRequestError):
62 """The version is not supported."""
63
64
65class AuthenticationFailedError(StorageRequestError):
66 """The authencation failed."""
67
68
69class InternalError(StorageRequestError):
70 """There was an internal error on the other side."""
71
72
73class AuthenticationRequiredError(StorageRequestError):
74 """The authentication is required and hasn't been established yet."""
75
76
77class NoPermissionError(StorageRequestError):
78 """Current permissions are not the required ones."""
79
80
81class AlreadyExistsError(StorageRequestError):
82 """The node already exists."""
83
84
85class DoesNotExistError(StorageRequestError):
86 """The node does not exists."""
87
88
89class NotADirectoryError(StorageRequestError):
90 """The node is not a directory."""
91
92
93class NotEmptyError(StorageRequestError):
94 """The node is not empty."""
95
96
97class NotAvailableError(StorageRequestError):
98 """The node is not available."""
99
100
101class UploadInProgressError(StorageRequestError):
102 """There is already an upload in progress."""
103
104
105class UploadCorruptError(StorageRequestError):
106 """The upload is corrupted."""
107
108
109class UploadCanceledError(StorageRequestError):
110 """There upload was canceled."""
111
112
113class ConflictError(StorageRequestError):
114 """The was a conflict."""
115
116
117class TryAgainError(StorageRequestError):
118 """Server answered to try again."""
119
120
121class ProtocolError(StorageRequestError):
122 """There was a protocol error."""
123
124
125class QuotaExceededError(StorageRequestError):
126 """The quota was exceeded."""
127
128
129class InvalidFilenameError(StorageRequestError):
130 """The filename is invalid."""
131
132
133_error_mapping = {
134 protocol_pb2.Error.UNSUPPORTED_VERSION: UnsupportedVersionError,
135 protocol_pb2.Error.AUTHENTICATION_FAILED: AuthenticationFailedError,
136 protocol_pb2.Error.INTERNAL_ERROR: InternalError,
137 protocol_pb2.Error.AUTHENTICATION_REQUIRED: AuthenticationRequiredError,
138 protocol_pb2.Error.NO_PERMISSION: NoPermissionError,
139 protocol_pb2.Error.ALREADY_EXISTS: AlreadyExistsError,
140 protocol_pb2.Error.DOES_NOT_EXIST: DoesNotExistError,
141 protocol_pb2.Error.NOT_A_DIRECTORY: NotADirectoryError,
142 protocol_pb2.Error.NOT_EMPTY: NotEmptyError,
143 protocol_pb2.Error.NOT_AVAILABLE: NotAvailableError,
144 protocol_pb2.Error.UPLOAD_IN_PROGRESS: UploadInProgressError,
145 protocol_pb2.Error.UPLOAD_CORRUPT: UploadCorruptError,
146 protocol_pb2.Error.UPLOAD_CANCELED: UploadCanceledError,
147 protocol_pb2.Error.CONFLICT: ConflictError,
148 protocol_pb2.Error.TRY_AGAIN: TryAgainError,
149 protocol_pb2.Error.PROTOCOL_ERROR: ProtocolError,
150 protocol_pb2.Error.QUOTA_EXCEEDED: QuotaExceededError,
151 protocol_pb2.Error.INVALID_FILENAME: InvalidFilenameError,
152}
153
154def error_to_exception(error_code):
155 """Map protocol errors to specific exceptions."""
156 return _error_mapping[error_code]
0157
=== modified file 'ubuntuone/storageprotocol/request.py'
--- ubuntuone/storageprotocol/request.py 2010-01-04 18:21:24 +0000
+++ ubuntuone/storageprotocol/request.py 2010-04-01 18:11:31 +0000
@@ -36,6 +36,12 @@
36from zope.interface import implements36from zope.interface import implements
3737
38from ubuntuone.storageprotocol import protocol_pb2, validators38from ubuntuone.storageprotocol import protocol_pb2, validators
39from ubuntuone.storageprotocol.errors import (
40 StorageProtocolError, StorageProtocolErrorSizeTooBig,
41 StorageProtocolProtocolError, StorageRequestError,
42 RequestCancelledError, error_to_exception
43)
44
3945
40# the max possible packet size is 2**32 (32 bits for size)46# the max possible packet size is 2**32 (32 bits for size)
41# although we will not allow packets that big for now47# although we will not allow packets that big for now
@@ -53,41 +59,6 @@
53# the referred is the own root node, and not any of the shares59# the referred is the own root node, and not any of the shares
54ROOT = ''60ROOT = ''
5561
56class StorageProtocolError(Exception):
57 """base class for all client/server exceptions."""
58
59
60class StorageProtocolErrorSizeTooBig(StorageProtocolError):
61 """the size we received was too big."""
62
63
64class StorageProtocolProtocolError(StorageProtocolError):
65 """A protocol error on the storage protocol."""
66
67
68class StorageRequestError(StorageProtocolError):
69 """an exception that keeps the request that generated it around."""
70
71 def __init__(self, request, message):
72 """create a StorageRequestError.
73
74 @param request: the request that generated this error.
75 @param message: the message received that generated the error.
76 """
77 error_name = protocol_pb2.Error.DESCRIPTOR \
78 .enum_types_by_name['ErrorType'] \
79 .values_by_number[message.error.type].name
80 super(StorageRequestError, self).__init__(error_name)
81 #: the request that generated the error
82 self.request = request
83 #: the message received that generated the error
84 self.error_message = message
85
86
87class RequestCancelledError(Exception):
88 """The request is cancelled."""
89
90
91class RequestHandler(Protocol):62class RequestHandler(Protocol):
92 """the base class for a network peer.63 """the base class for a network peer.
9364
@@ -419,6 +390,14 @@
419 """override this method to start the request."""390 """override this method to start the request."""
420 raise NotImplementedError("request needs to do something")391 raise NotImplementedError("request needs to do something")
421392
393 def _default_process_message(self, message):
394 """Map ERROR message to a specific exception."""
395 if message.type == protocol_pb2.Message.ERROR:
396 error_class = error_to_exception(message.error.type)
397 else:
398 error_class = StorageRequestError
399 self.error(error_class(self, message))
400
422 def processMessage(self, message):401 def processMessage(self, message):
423 """handle an incoming message for this request. override this.402 """handle an incoming message for this request. override this.
424403
425404
=== modified file 'ubuntuone/storageprotocol/volumes.py'
--- ubuntuone/storageprotocol/volumes.py 2009-12-22 19:25:50 +0000
+++ ubuntuone/storageprotocol/volumes.py 2010-04-01 18:11:31 +0000
@@ -1,3 +1,5 @@
1# -*- coding: utf-8 -*-
2#
1# Author: Natalia B. Bidart <natalia.bidart@canonical.com>3# Author: Natalia B. Bidart <natalia.bidart@canonical.com>
2#4#
3# Copyright 2009 Canonical Ltd.5# Copyright 2009 Canonical Ltd.

Subscribers

People subscribed via source and target branches