summaryrefslogtreecommitdiff
path: root/src/leap/baseapp/eip.py
diff options
context:
space:
mode:
authorkali <kali@leap.se>2012-09-06 02:27:04 +0900
committerkali <kali@leap.se>2012-09-06 02:27:04 +0900
commit8148bc9c8c113c41fcb18b397669b1f13447c653 (patch)
tree226ed4f238369f8937c28e3d0f11258cbfb7b506 /src/leap/baseapp/eip.py
parentc190b7f66cc1977d0e058bfa2d8fc1a850326320 (diff)
more generic error handler in EipConductorAppMixin
documentation of the Exception Hierarchy and attributes. also a bit of general cleanup around error handling in conductor. Hopefully to be polished an abstracted to leap.base with time. not all errors are converted (and the old with_errors/ignoring errors) are still there, but we should be using this style of handlers from now on. wrapping up with this pseudo-feature for now. as we work on individual features we can mimick the exceptions that are working.
Diffstat (limited to 'src/leap/baseapp/eip.py')
-rw-r--r--src/leap/baseapp/eip.py150
1 files changed, 77 insertions, 73 deletions
diff --git a/src/leap/baseapp/eip.py b/src/leap/baseapp/eip.py
index dd88b7f5..afdb7adc 100644
--- a/src/leap/baseapp/eip.py
+++ b/src/leap/baseapp/eip.py
@@ -11,8 +11,7 @@ from leap.eip.eipconnection import EIPConnection
logger = logging.getLogger(name=__name__)
-class EIPConductorApp(object):
- # XXX EIPConductorMixin ?
+class EIPConductorAppMixin(object):
"""
initializes an instance of EIPConnection,
gathers errors, and passes status-change signals
@@ -52,86 +51,90 @@ class EIPConductorApp(object):
lambda: self.start_or_stopVPN())
def error_check(self):
+ """
+ consumes the conductor error queue.
+ pops errors, and acts accordingly (launching user dialogs).
+ """
logger.debug('error check')
#####################################
# XXX refactor in progress (by #504)
+
errq = self.conductor.error_queue
while errq.qsize() != 0:
logger.debug('%s errors left in conductor queue', errq.qsize())
error = errq.get()
+
+ # redundant log, debugging the loop.
logger.error('%s: %s', error.__class__.__name__, error.message)
if issubclass(error.__class__, eip_exceptions.EIPClientError):
- if error.critical:
- logger.critical(error.message)
- logger.error('quitting')
-
- # XXX
- # check headless = False before
- # launching dialog.
- # (for Qt tests)
-
- dialog = ErrorDialog()
- if getattr(error, 'usermessage', None):
- message = error.usermessage
- else:
- message = error.message
- dialog.criticalMessage(message, 'error')
- else:
- logger.exception(error.message)
+ self.handle_eip_error(error)
+
else:
+ # This is not quite working. FIXME
import traceback
traceback.print_exc()
raise error
- if self.conductor.missing_definition is True:
- dialog = ErrorDialog()
- dialog.criticalMessage(
- 'The default '
- 'definition.json file cannot be found',
- 'error')
+ if error.failfirst is True:
+ break
- if self.conductor.missing_provider is True:
- dialog = ErrorDialog()
- dialog.criticalMessage(
- 'Missing provider. Add a remote_ip entry '
- 'under section [provider] in eip.cfg',
- 'error')
+ #############################################
+ # old errors to check
+ # write test for them and them remove
+ # their corpses from here.
- if self.conductor.missing_vpn_keyfile is True:
- dialog = ErrorDialog()
- dialog.criticalMessage(
- 'Could not find the vpn keys file',
- 'error')
+ #if self.conductor.missing_vpn_keyfile is True:
+ #dialog = ErrorDialog()
+ #dialog.criticalMessage(
+ #'Could not find the vpn keys file',
+ #'error')
- # ... btw, review pending.
- # os.kill of subprocess fails if we have
- # some of this errors.
+ #if self.conductor.bad_keyfile_perms is True:
+ #dialog = ErrorDialog()
+ #dialog.criticalMessage(
+ #'The vpn keys file has bad permissions',
+ #'error')
- # deprecated.
- # get something alike.
- #if self.conductor.bad_provider is True:
+ # deprecated. configchecker takes care of that.
+ #if self.conductor.missing_definition is True:
#dialog = ErrorDialog()
#dialog.criticalMessage(
- #'Bad provider entry. Check that remote_ip entry '
- #'has an IP under section [provider] in eip.cfg',
+ #'The default '
+ #'definition.json file cannot be found',
#'error')
- if self.conductor.bad_keyfile_perms is True:
- dialog = ErrorDialog()
- dialog.criticalMessage(
- 'The vpn keys file has bad permissions',
- 'error')
+ def handle_eip_error(self, error):
+ """
+ check severity and launches
+ dialogs informing user about the errors.
+ in the future we plan to derive errors to
+ our log viewer.
+ """
- if self.conductor.missing_pkexec is True:
+ if getattr(error, 'usermessage', None):
+ message = error.usermessage
+ else:
+ message = error.message
+
+ # XXX
+ # check headless = False before
+ # launching dialog.
+ # (so Qt tests can assert stuff)
+
+ if error.critical:
+ logger.critical(error.message)
+ #critical error (non recoverable),
+ #we give user some info and quit.
+ #(critical error dialog will exit app)
+ ErrorDialog(errtype="critical",
+ msg=message,
+ label="critical error")
+
+ else:
dialog = ErrorDialog()
- dialog.warningMessage(
- 'We could not find <b>pkexec</b> in your '
- 'system.<br/> Do you want to try '
- '<b>setuid workaround</b>? '
- '(<i>DOES NOTHING YET</i>)',
- 'error')
+ dialog.warningMessage(message, 'error')
@QtCore.pyqtSlot()
def statusUpdate(self):
@@ -188,29 +191,30 @@ class EIPConductorApp(object):
"""
stub for running child process with vpn
"""
+ if self.conductor.has_errors():
+ logger.debug('not starting vpn; conductor has errors')
+
if self.eip_service_started is False:
try:
self.conductor.connect()
- # XXX move this to error queue
- except eip_exceptions.EIPNoCommandError:
- dialog = ErrorDialog()
- dialog.warningMessage(
- 'No suitable openvpn command found. '
- '<br/>(Might be a permissions problem)',
- 'error')
- if self.debugmode:
- self.startStopButton.setText('&Disconnect')
- self.eip_service_started = True
- # XXX what is optimum polling interval?
- # too little is overkill, too much
- # will miss transition states..
+ except eip_exceptions.EIPNoCommandError as exc:
+ self.handle_eip_error(exc)
+
+ except Exception as err:
+ # raise generic exception (Bad Thing Happened?)
+ logger.exception(err)
+ else:
+ # no errors, so go on.
+ if self.debugmode:
+ self.startStopButton.setText('&Disconnect')
+ self.eip_service_started = True
- # XXX decouple! (timer is init by icons class).
- # should bring it here?
- # to its own class?
+ # XXX decouple! (timer is init by icons class).
+ # we could bring Timer Init to this Mixin
+ # or to its own Mixin.
+ self.timer.start(constants.TIMER_MILLISECONDS)
- self.timer.start(constants.TIMER_MILLISECONDS)
return
if self.eip_service_started is True: