vpp-api: Add context to VPPStatsIOError.

* Provide context information and return meaningful information.
VPPStatsIOError: Stat segment client connection returned: -2 Stat client socket open but couldn't connect.

Change-Id: I14ea35c58452a2cb7598a7efd136f0c7e1f5743a
Signed-off-by: Paul Vinciguerra <pvinci@vinciconsulting.com>
diff --git a/src/vpp-api/client/stat_client.c b/src/vpp-api/client/stat_client.c
index bb7f240..2cf53d5 100644
--- a/src/vpp-api/client/stat_client.c
+++ b/src/vpp-api/client/stat_client.c
@@ -124,14 +124,14 @@
       0)
     {
       close (sock);
-      return -1;
+      return -2;
     }
 
   if ((mfd = recv_fd (sock)) < 0)
     {
       close (sock);
       fprintf (stderr, "Receiving file descriptor failed\n");
-      return -1;
+      return -3;
     }
   close (sock);
 
@@ -142,13 +142,13 @@
   if (fstat (mfd, &st) == -1)
     {
       perror ("mmap fstat failed");
-      return -1;
+      return -4;
     }
   if ((memaddr =
        mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, mfd, 0)) == MAP_FAILED)
     {
       perror ("mmap map failed");
-      return -1;
+      return -5;
     }
 
   sm->memory_size = st.st_size;
diff --git a/src/vpp-api/python/vpp_papi/vpp_stats.py b/src/vpp-api/python/vpp_papi/vpp_stats.py
index 06daaf8..0afed26 100644
--- a/src/vpp-api/python/vpp_papi/vpp_stats.py
+++ b/src/vpp-api/python/vpp_papi/vpp_stats.py
@@ -128,7 +128,6 @@
     # Scalar index
     if e.type == 1:
         return e.scalar_value
-        return None
     if e.type == 2:
         return simple_counter_vec_list(api, e.simple_counter_vec)
     if e.type == 3:
@@ -139,7 +138,30 @@
 
 
 class VPPStatsIOError(IOError):
-    pass
+    message = "Stat segment client connection returned: " \
+              "%(retval)s %(strerror)s."
+
+    strerror = {-1: "Stat client couldn't open socket",
+                -2: "Stat client socket open but couldn't connect",
+                -3: "Receiving file descriptor failed",
+                -4: "mmap fstat failed",
+                -5: "mmap map failed"
+                }
+
+    def __init__(self, message=None, **kwargs):
+        if 'retval' in kwargs:
+            self.retval = kwargs['retval']
+            kwargs['strerror'] = self.strerror[int(self.retval)]
+
+        if not message:
+            try:
+                message = self.message % kwargs
+            except Exception as e:
+                message = self.message
+        else:
+            message = message % kwargs
+
+        super(VPPStatsIOError, self).__init__(message)
 
 
 class VPPStatsClientLoadError(RuntimeError):
@@ -168,7 +190,7 @@
                 break
 
         if rv != 0:
-            raise VPPStatsIOError()
+            raise VPPStatsIOError(retval=rv)
 
     def heartbeat(self):
         return self.api.stat_segment_heartbeat_r(self.client)