# HG changeset patch # User Goffi # Date 1371772837 -7200 # Node ID d207c21865197375f574d66413c8557491296fd1 # Parent 190ccc6dc36c8f819a86ed4279b2be8f2bd9f94a 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 diff -r 190ccc6dc36c -r d207c2186519 frontends/src/bridge/DBus.py --- 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() diff -r 190ccc6dc36c -r d207c2186519 frontends/src/jp/jp --- 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 diff -r 190ccc6dc36c -r d207c2186519 frontends/src/quick_frontend/quick_app.py --- 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 . +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) diff -r 190ccc6dc36c -r d207c2186519 src/bridge/DBus.py --- 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) diff -r 190ccc6dc36c -r d207c2186519 src/bridge/bridge_constructor/dbus_core_template.py --- 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) diff -r 190ccc6dc36c -r d207c2186519 src/bridge/bridge_constructor/dbus_frontend_template.py --- 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() diff -r 190ccc6dc36c -r d207c2186519 src/core/exceptions.py --- 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 diff -r 190ccc6dc36c -r d207c2186519 src/core/sat_main.py --- 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)