Repository: google/mobly

Issue:
Socket errors thrown from device obj are not marked with device tag
We should wrap `socket.error` with a child class of `DeviceError`.


Discussion:

Resolving patch:
diff --git a/mobly/controllers/android_device_lib/jsonrpc_client_base.py b/mobly/controllers/android_device_lib/jsonrpc_client_base.py
--- a/mobly/controllers/android_device_lib/jsonrpc_client_base.py
+++ b/mobly/controllers/android_device_lib/jsonrpc_client_base.py
@@ -214,8 +214,8 @@ def connect(self, uid=UNKNOWN_UID, cmd=JsonRpcCommand.INIT):
 
         resp = self._cmd(cmd, uid)
         if not resp:
-            raise ProtocolError(
-                self._ad, ProtocolError.NO_RESPONSE_FROM_HANDSHAKE)
+            raise ProtocolError(self._ad,
+                                ProtocolError.NO_RESPONSE_FROM_HANDSHAKE)
         result = json.loads(str(resp, encoding='utf8'))
         if result['status']:
             self.uid = result['uid']
@@ -228,6 +228,40 @@ def disconnect(self):
             self._conn.close()
             self._conn = None
 
+    def _client_send(self, msg):
+        """Sends an Rpc message through the connection.
+
+        Args:
+            msg: string, the message to send.
+
+        Raises:
+            Error: a socket error occurred during the send.
+        """
+        try:
+            self._client.write(msg.encode("utf8") + b'\n')
+            self._client.flush()
+        except socket.error as e:
+            raise Error(
+                self._ad,
+                'Encountered socket error "%s" sending RPC message "%s"' %
+                (e, msg))
+
+    def _client_receive(self):
+        """Receives the server's response of an Rpc message.
+
+        Returns:
+            Raw byte string of the response.
+
+        Raises:
+            Error: a socket error occurred during the read.
+        """
+        try:
+            return self._client.readline()
+        except socket.error as e:
+            raise Error(
+                self._ad,
+                'Encountered socket error reading RPC response "%s"' % e)
+
     def _cmd(self, command, uid=None):
         """Send a command to the server.
 
@@ -240,13 +274,8 @@ def _cmd(self, command, uid=None):
         """
         if not uid:
             uid = self.uid
-        self._client.write(
-            json.dumps({
-                'cmd': command,
-                'uid': uid
-            }).encode("utf8") + b'\n')
-        self._client.flush()
-        return self._client.readline()
+        self._client_send(json.dumps({'cmd': command, 'uid': uid}))
+        return self._client_receive()
 
     def _rpc(self, method, *args):
         """Sends an rpc to the app.
@@ -266,9 +295,8 @@ def _rpc(self, method, *args):
             apiid = next(self._counter)
             data = {'id': apiid, 'method': method, 'params': args}
             request = json.dumps(data)
-            self._client.write(request.encode("utf8") + b'\n')
-            self._client.flush()
-            response = self._client.readline()
+            self._client_send(request)
+            response = self._client_receive()
         if not response:
             raise ProtocolError(self._ad,
                                 ProtocolError.NO_RESPONSE_FROM_SERVER)


Test patch: