changeset 627:d207c2186519

core, bridge, jp, quick_frontend: SàT stop more gracefully if bridge can't be initialised: - new BridgeInitError and BridgeExceptionNoService are in core.exceptions - D-Bus NotSupported is catched in bridge, and launch a BridgeInitError - BridgeInitError stop SàT core, jp, and quick_frontends with an explanation message. fix bug 27
author Goffi <goffi@goffi.org>
date Fri, 21 Jun 2013 02:00:37 +0200
parents 190ccc6dc36c
children 42ee0b0b0a15
files frontends/src/bridge/DBus.py frontends/src/jp/jp frontends/src/quick_frontend/quick_app.py src/bridge/DBus.py src/bridge/bridge_constructor/dbus_core_template.py src/bridge/bridge_constructor/dbus_frontend_template.py src/core/exceptions.py src/core/sat_main.py
diffstat 8 files changed, 55 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/src/bridge/DBus.py	Thu Jun 20 17:44:27 2013 +0200
+++ b/frontends/src/bridge/DBus.py	Fri Jun 21 02:00:37 2013 +0200
@@ -20,6 +20,7 @@
 from bridge_frontend import BridgeFrontend
 import dbus
 from logging import debug, error
+from sat.core.exceptions import BridgeExceptionNoService, BridgeInitError
 
 from dbus.mainloop.glib import DBusGMainLoop
 DBusGMainLoop(set_as_default=True)
@@ -31,10 +32,6 @@
 const_PLUGIN_SUFFIX = ".plugin"
 
 
-class BridgeExceptionNoService(Exception):
-    pass
-
-
 class DBusBridgeFrontend(BridgeFrontend):
     def __init__(self):
         try:
@@ -48,6 +45,9 @@
         except dbus.exceptions.DBusException, e:
             if e._dbus_error_name == 'org.freedesktop.DBus.Error.ServiceUnknown':
                 raise BridgeExceptionNoService
+            elif e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported':
+                print u"D-Bus is not launched, please see README to see instructions on how to launch it"
+                raise BridgeInitError
             else:
                 raise e
         #props = self.db_core_iface.getProperties()
--- a/frontends/src/jp/jp	Thu Jun 20 17:44:27 2013 +0200
+++ b/frontends/src/jp/jp	Fri Jun 21 02:00:37 2013 +0200
@@ -53,7 +53,8 @@
 from optparse import OptionParser
 from sat.tools.jid import JID
 import gobject
-from sat_frontends.bridge.DBus import DBusBridgeFrontend,BridgeExceptionNoService
+from sat_frontends.bridge.DBus import DBusBridgeFrontend
+from sat.core.exceptions import BridgeExceptionNoService, BridgeInitError
 from sat.tools.utils import clean_ustr
 import tarfile
 import tempfile
@@ -74,7 +75,9 @@
             self.bridge=DBusBridgeFrontend()
         except BridgeExceptionNoService:
             print(_(u"Can't connect to SàT backend, are you sure it's launched ?"))
-            import sys
+            sys.exit(1)
+        except BridgeInitError:
+            print(_(u"Can't init bridge"))
             sys.exit(1)
         self.transfer_data = None
 
--- a/frontends/src/quick_frontend/quick_app.py	Thu Jun 20 17:44:27 2013 +0200
+++ b/frontends/src/quick_frontend/quick_app.py	Fri Jun 21 02:00:37 2013 +0200
@@ -17,9 +17,11 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+import sys
 from logging import debug, info, warning, error
 from sat.tools.jid  import JID
-from sat_frontends.bridge.DBus import DBusBridgeFrontend,BridgeExceptionNoService
+from sat_frontends.bridge.DBus import DBusBridgeFrontend
+from sat.core.exceptions import BridgeExceptionNoService, BridgeInitError
 from sat_frontends.quick_frontend.quick_utils import escapePrivate, unescapePrivate
 from optparse import OptionParser
 
@@ -41,7 +43,9 @@
             self.bridge=DBusBridgeFrontend()
         except BridgeExceptionNoService:
             print(_(u"Can't connect to SàT backend, are you sure it's launched ?"))
-            import sys
+            sys.exit(1)
+        except BridgeInitError:
+            print(_(u"Can't init bridge"))
             sys.exit(1)
         self.bridge.register("connected", self.connected)
         self.bridge.register("disconnected", self.disconnected)
--- a/src/bridge/DBus.py	Thu Jun 20 17:44:27 2013 +0200
+++ b/src/bridge/DBus.py	Fri Jun 21 02:00:37 2013 +0200
@@ -24,6 +24,7 @@
 import inspect
 from logging import debug, info, error
 from twisted.internet.defer import Deferred
+from sat.core.exceptions import BridgeInitError
 
 const_INT_PREFIX = "org.goffi.SAT"  # Interface prefix
 const_ERROR_PREFIX = const_INT_PREFIX + ".error"
@@ -506,7 +507,12 @@
         dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
         Bridge.__init__(self)
         info("Init DBus...")
-        self.session_bus = dbus.SessionBus()
+        try:
+            self.session_bus = dbus.SessionBus()
+        except dbus.DBusException as e:
+            if e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported':
+                print u"D-Bus is not launched, please see README to see instructions on how to launch it"
+            raise BridgeInitError
         self.dbus_name = dbus.service.BusName(const_INT_PREFIX, self.session_bus)
         self.dbus_bridge = DbusObject(self.session_bus, const_OBJ_PATH)
 
--- a/src/bridge/bridge_constructor/dbus_core_template.py	Thu Jun 20 17:44:27 2013 +0200
+++ b/src/bridge/bridge_constructor/dbus_core_template.py	Fri Jun 21 02:00:37 2013 +0200
@@ -24,6 +24,7 @@
 import inspect
 from logging import debug, info, error
 from twisted.internet.defer import Deferred
+from sat.core.exceptions import BridgeInitError
 
 const_INT_PREFIX = "org.goffi.SAT"  # Interface prefix
 const_ERROR_PREFIX = const_INT_PREFIX + ".error"
@@ -204,7 +205,12 @@
         dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
         Bridge.__init__(self)
         info("Init DBus...")
-        self.session_bus = dbus.SessionBus()
+        try:
+            self.session_bus = dbus.SessionBus()
+        except dbus.DBusException as e:
+            if e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported':
+                print u"D-Bus is not launched, please see README to see instructions on how to launch it"
+            raise BridgeInitError
         self.dbus_name = dbus.service.BusName(const_INT_PREFIX, self.session_bus)
         self.dbus_bridge = DbusObject(self.session_bus, const_OBJ_PATH)
 
--- a/src/bridge/bridge_constructor/dbus_frontend_template.py	Thu Jun 20 17:44:27 2013 +0200
+++ b/src/bridge/bridge_constructor/dbus_frontend_template.py	Fri Jun 21 02:00:37 2013 +0200
@@ -20,6 +20,7 @@
 from bridge_frontend import BridgeFrontend
 import dbus
 from logging import debug, error
+from sat.core.exceptions import BridgeExceptionNoService, BridgeInitError
 
 from dbus.mainloop.glib import DBusGMainLoop
 DBusGMainLoop(set_as_default=True)
@@ -31,10 +32,6 @@
 const_PLUGIN_SUFFIX = ".plugin"
 
 
-class BridgeExceptionNoService(Exception):
-    pass
-
-
 class DBusBridgeFrontend(BridgeFrontend):
     def __init__(self):
         try:
@@ -48,6 +45,9 @@
         except dbus.exceptions.DBusException, e:
             if e._dbus_error_name == 'org.freedesktop.DBus.Error.ServiceUnknown':
                 raise BridgeExceptionNoService
+            elif e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported':
+                print u"D-Bus is not launched, please see README to see instructions on how to launch it"
+                raise BridgeInitError
             else:
                 raise e
         #props = self.db_core_iface.getProperties()
--- a/src/core/exceptions.py	Thu Jun 20 17:44:27 2013 +0200
+++ b/src/core/exceptions.py	Fri Jun 21 02:00:37 2013 +0200
@@ -44,3 +44,9 @@
 
 class DataError(Exception):
     pass
+
+class BridgeInitError(Exception):
+    pass
+
+class BridgeExceptionNoService(Exception):
+    pass
--- a/src/core/sat_main.py	Thu Jun 20 17:44:27 2013 +0200
+++ b/src/core/sat_main.py	Fri Jun 21 02:00:37 2013 +0200
@@ -37,7 +37,7 @@
 
 from sat.core.default_config import CONST
 from sat.core import xmpp
-from sat.core.exceptions import ProfileUnknownError, UnknownEntityError, ProfileNotInCacheError
+from sat.core import exceptions
 from sat.memory.memory import Memory
 from sat.tools.xml_tools import tupleList2dataForm
 from sat.tools.misc import TriggerManager
@@ -105,7 +105,11 @@
 
         self.trigger = TriggerManager()  # trigger are used to change SàT behaviour
 
-        self.bridge = DBusBridge()
+        try:
+            self.bridge = DBusBridge()
+        except exceptions.BridgeInitError:
+            print (u"Bridge can't be initialised, can't start SàT core") # reactor is not launched yet, so we can't use error log
+            sys.exit(1)
         self.bridge.register("getVersion", lambda: self.get_const('client_version'))
         self.bridge.register("getProfileName", self.memory.getProfileName)
         self.bridge.register("getProfilesList", self.memory.getProfilesList)
@@ -207,7 +211,7 @@
         profile = self.memory.getProfileName(profile_key)
         if not profile:
             error(_('Trying to connect a non-exsitant profile'))
-            raise ProfileUnknownError(profile_key)
+            raise exceptions.ProfileUnknownError(profile_key)
 
         if self.isConnected(profile):
             info(_("already connected !"))
@@ -277,7 +281,7 @@
     def getContacts(self, profile_key):
         client = self.getClient(profile_key)
         if not client:
-            raise ProfileUnknownError(_('Asking contacts for a non-existant profile'))
+            raise exceptions.ProfileUnknownError(_('Asking contacts for a non-existant profile'))
         ret = []
         for item in client.roster.getItems():  # we get all items for client's roster
             # and convert them to expected format
@@ -288,7 +292,7 @@
     def getContactsFromGroup(self, group, profile_key):
         client = self.getClient(profile_key)
         if not client:
-            raise ProfileUnknownError(_("Asking group's contacts for a non-existant profile"))
+            raise exceptions.ProfileUnknownError(_("Asking group's contacts for a non-existant profile"))
         return client.roster.getJidsFromGroup(group)
 
     def purgeClient(self, profile):
@@ -458,7 +462,7 @@
         assert(profile_key)
         client = self.getClient(profile_key)
         if not client:
-            raise ProfileNotInCacheError
+            raise exceptions.ProfileNotInCacheError
         ret = []
         for conf_id in client._waiting_conf:
             conf_type, data = client._waiting_conf[conf_id][:2]
@@ -491,7 +495,7 @@
                 try:
                     entity_type = self.memory.getEntityData(mess_data["to"], ['type'], profile)["type"]
                     #FIXME: should entity_type manage ressources ?
-                except (UnknownEntityError, KeyError):
+                except (exceptions.UnknownEntityError, KeyError):
                     entity_type = "contact"
 
                 if entity_type == "chatroom":
@@ -642,7 +646,7 @@
         """
         client = self.getClient(profile)
         if not client:
-            raise ProfileUnknownError(_("Asking confirmation a non-existant profile"))
+            raise exceptions.ProfileUnknownError(_("Asking confirmation a non-existant profile"))
         if conf_id in client._waiting_conf:
             error(_("Attempt to register two callbacks for the same confirmation"))
         else:
@@ -653,7 +657,7 @@
         """Called by frontends to answer confirmation requests"""
         client = self.getClient(profile)
         if not client:
-            raise ProfileUnknownError(_("Confirmation answer from a non-existant profile"))
+            raise exceptions.ProfileUnknownError(_("Confirmation answer from a non-existant profile"))
         debug(_("Received confirmation answer for conf_id [%(conf_id)s]: %(success)s") % {'conf_id': conf_id, 'success': _("accepted") if accepted else _("refused")})
         if conf_id not in client._waiting_conf:
             error(_("Received an unknown confirmation (%(id)s for %(profile)s)") % {'id': conf_id, 'profile': profile})
@@ -666,14 +670,14 @@
         """Register a callback called when progress is requested for id"""
         client = self.getClient(profile)
         if not client:
-            raise ProfileUnknownError
+            raise exceptions.ProfileUnknownError
         client._progress_cb_map[progress_id] = CB
 
     def removeProgressCB(self, progress_id, profile):
         """Remove a progress callback"""
         client = self.getClient(profile)
         if not client:
-            raise ProfileUnknownError
+            raise exceptions.ProfileUnknownError
         if progress_id not in client._progress_cb_map:
             error(_("Trying to remove an unknow progress callback"))
         else:
@@ -686,7 +690,7 @@
         """
         client = self.getClient(profile)
         if not profile:
-            raise ProfileNotInCacheError
+            raise exceptions.ProfileNotInCacheError
         data = {}
         try:
             client._progress_cb_map[progress_id](progress_id, data, profile)