[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Expanding contorller exception types
commit efe28987ffd27e69a2c6c566bdad2efc5f16e93e
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Sat Nov 12 15:55:09 2011 -0800
Expanding contorller exception types
Exception types pretty much mirror what TorCtl has (protocol error, socket
error, and controller closed) with a base type users can catch instead. One
difference though is that if stem functions raise a socket.error (without
documenting that they do) then that's a bug - those errors should cuase a
stem.types.SocketError instead.
---
stem/types.py | 34 +++++++++++++++++++++-------------
test/integ/message.py | 14 +++++++-------
test/integ/system.py | 3 ++-
test/unit/types/control_message.py | 2 +-
4 files changed, 31 insertions(+), 22 deletions(-)
diff --git a/stem/types.py b/stem/types.py
index e03698c..78e2fd9 100644
--- a/stem/types.py
+++ b/stem/types.py
@@ -2,8 +2,10 @@
Class representations for a variety of tor objects. These are most commonly
return values rather than being instantiated by users directly.
-ProtocolError - Malformed socket data.
-ControlSocketClosed - Socket terminated.
+ControllerError - Base exception raised when using the controller.
+ |- ProtocolError - Malformed socket data.
+ |- SocketError - Socket used for controller communication errored.
+ +- SocketClosed - Socket terminated.
read_message - Reads a ControlMessage from a control socket.
ControlMessage - Message from the control socket.
@@ -45,11 +47,18 @@ KEY_ARG = re.compile("^(\S+)=")
CONTROL_ESCAPES = {r"\\": "\\", r"\"": "\"", r"\'": "'",
r"\r": "\r", r"\n": "\n", r"\t": "\t"}
-class ProtocolError(Exception):
+class ControllerError(Exception):
+ "Base error for controller communication issues."
+
+class ProtocolError(ControllerError):
"Malformed content from the control socket."
pass
-class ControlSocketClosed(Exception):
+class SocketError(ControllerError):
+ "Error arose while communicating with the control socket."
+ pass
+
+class SocketClosed(ControllerError):
"Control socket was closed before completing the message."
pass
@@ -67,8 +76,7 @@ def read_message(control_file):
Raises:
ProtocolError the content from the socket is malformed
- ControlSocketClosed if the socket closes before we receive a complete
- message
+ SocketClosed if the socket closes before we receive a complete message
"""
parsed_content, raw_content = [], ""
@@ -79,11 +87,11 @@ def read_message(control_file):
# if the control_file has been closed then we will receive:
# AttributeError: 'NoneType' object has no attribute 'recv'
- LOGGER.warn("ControlSocketClosed: socket file has been closed")
- raise ControlSocketClosed("socket file has been closed")
+ LOGGER.warn("SocketClosed: socket file has been closed")
+ raise SocketClosed("socket file has been closed")
except socket.error, exc:
- LOGGER.warn("ControlSocketClosed: received an exception (%s)" % exc)
- raise ControlSocketClosed(exc)
+ LOGGER.warn("SocketClosed: received an exception (%s)" % exc)
+ raise SocketClosed(exc)
raw_content += line
@@ -94,8 +102,8 @@ def read_message(control_file):
# if the socket is disconnected then the readline() method will provide
# empty content
- LOGGER.warn("ControlSocketClosed: empty socket content")
- raise ControlSocketClosed("Received empty socket content.")
+ LOGGER.warn("SocketClosed: empty socket content")
+ raise SocketClosed("Received empty socket content.")
elif len(line) < 4:
LOGGER.warn("ProtocolError: line too short (%s)" % line)
raise ProtocolError("Badly formatted reply line: too short")
@@ -125,7 +133,7 @@ def read_message(control_file):
while True:
try: line = control_file.readline()
- except socket.error, exc: raise ControlSocketClosed(exc)
+ except socket.error, exc: raise SocketClosed(exc)
raw_content += line
diff --git a/test/integ/message.py b/test/integ/message.py
index 531d4a2..a562f86 100644
--- a/test/integ/message.py
+++ b/test/integ/message.py
@@ -40,16 +40,16 @@ class TestMessageFunctions(unittest.TestCase):
control_socket_file.write("GETINFO version\r\n")
control_socket_file.flush()
- self.assertRaises(stem.types.ControlSocketClosed, stem.types.read_message, control_socket_file)
+ self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
# Additional socket usage should fail, and pulling more responses will fail
# with more closed exceptions.
control_socket_file.write("GETINFO version\r\n")
self.assertRaises(socket.error, control_socket_file.flush)
- self.assertRaises(stem.types.ControlSocketClosed, stem.types.read_message, control_socket_file)
- self.assertRaises(stem.types.ControlSocketClosed, stem.types.read_message, control_socket_file)
- self.assertRaises(stem.types.ControlSocketClosed, stem.types.read_message, control_socket_file)
+ self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
+ self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
+ self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
# The socket connection is already broken so calling close shouldn't have
# an impact.
@@ -57,7 +57,7 @@ class TestMessageFunctions(unittest.TestCase):
control_socket.close()
control_socket_file.write("GETINFO version\r\n")
self.assertRaises(socket.error, control_socket_file.flush)
- self.assertRaises(stem.types.ControlSocketClosed, stem.types.read_message, control_socket_file)
+ self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
# Closing the file handler, however, will cause a different type of error.
# This seems to depend on the python version, in 2.6 we get an
@@ -72,8 +72,8 @@ class TestMessageFunctions(unittest.TestCase):
# receives: AttributeError: 'NoneType' object has no attribute 'sendall'
self.assertRaises(AttributeError, control_socket_file.flush)
- # receives: stem.types.ControlSocketClosed: socket file has been closed
- self.assertRaises(stem.types.ControlSocketClosed, stem.types.read_message, control_socket_file)
+ # receives: stem.types.SocketClosed: socket file has been closed
+ self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
def test_invalid_command(self):
"""
diff --git a/test/integ/system.py b/test/integ/system.py
index 4aa5d15..09ffd24 100644
--- a/test/integ/system.py
+++ b/test/integ/system.py
@@ -49,7 +49,8 @@ class TestSystemFunctions(unittest.TestCase):
# tor's pwd will match our process since we started it
runner = test.runner.get_runner()
self.assertEquals(os.getcwd(), system.get_cwd(runner.get_pid()))
- self.assertRaises(IOError, system.get_cwd, 99999)
+ self.assertEquals(None, system.get_cwd(99999, True))
+ self.assertRaises(IOError, system.get_cwd, 99999, False)
def test_get_bsd_jail_id(self):
"""
diff --git a/test/unit/types/control_message.py b/test/unit/types/control_message.py
index 563a0bf..5e9b7bc 100644
--- a/test/unit/types/control_message.py
+++ b/test/unit/types/control_message.py
@@ -156,7 +156,7 @@ class TestControlMessage(unittest.TestCase):
control_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
control_socket_file = control_socket.makefile()
- self.assertRaises(stem.types.ControlSocketClosed, stem.types.read_message, control_socket_file)
+ self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
def assert_message_parses(self, controller_reply):
"""
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits