changeset 1073:f094583732de

bridge: DBusException also transports the twisted failure condition
author souliane <souliane@mailoo.org>
date Sun, 15 Jun 2014 16:06:02 +0200
parents d123d61976c8
children a47995155e55
files frontends/src/bridge/DBus.py frontends/src/bridge/bridge_frontend.py src/bridge/DBus.py src/bridge/bridge_constructor/dbus_core_template.py src/bridge/bridge_constructor/dbus_frontend_template.py
diffstat 5 files changed, 45 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/src/bridge/DBus.py	Sun Jun 15 00:18:28 2014 +0200
+++ b/frontends/src/bridge/DBus.py	Sun Jun 15 16:06:02 2014 +0200
@@ -27,6 +27,8 @@
 from dbus.mainloop.glib import DBusGMainLoop
 DBusGMainLoop(set_as_default=True)
 
+import ast
+
 const_INT_PREFIX = "org.goffi.SAT"  # Interface prefix
 const_ERROR_PREFIX = const_INT_PREFIX + ".error"
 const_OBJ_PATH = '/org/goffi/SAT/bridge'
@@ -42,7 +44,15 @@
     @return: BridgeException
     """
     name = dbus_e.get_dbus_name()[len(const_ERROR_PREFIX) + 1:]
-    return BridgeException(name, dbus_e.get_dbus_message())
+    # XXX: dbus_e.args doesn't contain the original DBusException args, but we
+    # receive its serialized form in dbus_e.args[0]. From that we can rebuild
+    # the original arguments list thanks to ast.literal_eval (secure eval).
+    message = dbus_e.get_dbus_message()  # similar to dbus_e.args[0]
+    try:
+        message, condition = ast.literal_eval(message)
+    except (SyntaxError, ValueError, TypeError):
+        condition = ''
+    return BridgeException(name, message, condition)
 
 
 class DBusBridgeFrontend(BridgeFrontend):
--- a/frontends/src/bridge/bridge_frontend.py	Sun Jun 15 00:18:28 2014 +0200
+++ b/frontends/src/bridge/bridge_frontend.py	Sun Jun 15 16:06:02 2014 +0200
@@ -29,15 +29,17 @@
 class BridgeException(Exception):
     """An exception which has been raised from the backend and arrived to the frontend."""
 
-    def __init__(self, name, message):
+    def __init__(self, name, message='', condition=''):
         """
 
         @param name (str): full exception class name (with module)
         @param message (str): error message
+        @param condition (str) : error condition
         """
         Exception.__init__(self)
         self.fullname = unicode(name)
         self.message = unicode(message)
+        self.condition = unicode(condition) if condition else ''
         self.module, dummy, self.classname = unicode(self.fullname).rpartition('.')
 
     def __str__(self):
--- a/src/bridge/DBus.py	Sun Jun 15 00:18:28 2014 +0200
+++ b/src/bridge/DBus.py	Sun Jun 15 16:06:02 2014 +0200
@@ -57,6 +57,11 @@
 
 class GenericException(dbus.DBusException):
     def __init__(self, twisted_error):
+        """
+
+        @param twisted_error (Failure): instance of twisted Failure
+        @return: DBusException
+        """
         super(GenericException, self).__init__()
         try:
             # twisted_error.value is a class
@@ -64,7 +69,11 @@
         except TypeError:
             # twisted_error.value is an instance
             class_ = twisted_error.value.__class__
-            self.args = (twisted_error.getErrorMessage(),)
+            message = twisted_error.getErrorMessage()
+            try:
+                self.args = (message, twisted_error.value.condition)
+            except AttributeError:
+                self.args = (message,)
         self._dbus_error_name = '.'.join([const_ERROR_PREFIX, class_.__module__, class_.__name__])
 
 
--- a/src/bridge/bridge_constructor/dbus_core_template.py	Sun Jun 15 00:18:28 2014 +0200
+++ b/src/bridge/bridge_constructor/dbus_core_template.py	Sun Jun 15 16:06:02 2014 +0200
@@ -57,6 +57,11 @@
 
 class GenericException(dbus.DBusException):
     def __init__(self, twisted_error):
+        """
+
+        @param twisted_error (Failure): instance of twisted Failure
+        @return: DBusException
+        """
         super(GenericException, self).__init__()
         try:
             # twisted_error.value is a class
@@ -64,7 +69,11 @@
         except TypeError:
             # twisted_error.value is an instance
             class_ = twisted_error.value.__class__
-            self.args = (twisted_error.getErrorMessage(),)
+            message = twisted_error.getErrorMessage()
+            try:
+                self.args = (message, twisted_error.value.condition)
+            except AttributeError:
+                self.args = (message,)
         self._dbus_error_name = '.'.join([const_ERROR_PREFIX, class_.__module__, class_.__name__])
 
 
--- a/src/bridge/bridge_constructor/dbus_frontend_template.py	Sun Jun 15 00:18:28 2014 +0200
+++ b/src/bridge/bridge_constructor/dbus_frontend_template.py	Sun Jun 15 16:06:02 2014 +0200
@@ -27,6 +27,8 @@
 from dbus.mainloop.glib import DBusGMainLoop
 DBusGMainLoop(set_as_default=True)
 
+import ast
+
 const_INT_PREFIX = "org.goffi.SAT"  # Interface prefix
 const_ERROR_PREFIX = const_INT_PREFIX + ".error"
 const_OBJ_PATH = '/org/goffi/SAT/bridge'
@@ -42,7 +44,15 @@
     @return: BridgeException
     """
     name = dbus_e.get_dbus_name()[len(const_ERROR_PREFIX) + 1:]
-    return BridgeException(name, dbus_e.get_dbus_message())
+    # XXX: dbus_e.args doesn't contain the original DBusException args, but we
+    # receive its serialized form in dbus_e.args[0]. From that we can rebuild
+    # the original arguments list thanks to ast.literal_eval (secure eval).
+    message = dbus_e.get_dbus_message()  # similar to dbus_e.args[0]
+    try:
+        message, condition = ast.literal_eval(message)
+    except (SyntaxError, ValueError, TypeError):
+        condition = ''
+    return BridgeException(name, message, condition)
 
 
 class DBusBridgeFrontend(BridgeFrontend):