[kupfer] "Convert" OperationErrors to user error notifications in commandexec.py



commit 5c86c271ce24e9dd6bdc1fe4d3f4c89665d0ab08
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Sat Feb 13 15:50:39 2010 +0100

    "Convert" OperationErrors to user error notifications in commandexec.py
    
    When executing a command and encountering OperationError, we show an
    error already in commanexec.py (so we get an error regardless of from
    where the command was executed, including triggers).
    
    Error "conversion" means that we consume the error (if we succeed in
    showing an error dialog for it), but raise a more general action
    execution exception.

 kupfer/commandexec.py |   30 ++++++++++++++++++++++++++++--
 1 files changed, 28 insertions(+), 2 deletions(-)
---
diff --git a/kupfer/commandexec.py b/kupfer/commandexec.py
index 3f001a6..cc43bcb 100644
--- a/kupfer/commandexec.py
+++ b/kupfer/commandexec.py
@@ -26,11 +26,14 @@ merge multiple return values.
 from __future__ import with_statement
 
 import contextlib
+import sys
 
 import gobject
 
 from kupfer import pretty
 from kupfer import task
+from kupfer import uiutils
+from kupfer.objects import OperationError
 from kupfer.obj.objects import SourceLeaf
 from kupfer.obj.sources import MultiSource
 from kupfer.obj.compose import MultipleLeaf
@@ -146,6 +149,28 @@ class ActionExecutionContext (gobject.GObject, pretty.OutputMixin):
 	def _is_nested(self):
 		return self._nest_level
 
+	@contextlib.contextmanager
+	def _error_conversion(self, *cmdtuple):
+		try:
+			yield
+		except OperationError:
+			self.output_debug(sys.exc_info())
+			if not self.operation_error(sys.exc_info(), cmdtuple):
+				raise
+			raise ActionExecutionError("Encountered an Operation Error")
+
+	def operation_error(self, exc_info, cmdtuple):
+		"Error when executing action. Return True when error was handled"
+		if self._is_nested():
+			return
+		etype, value, tb = exc_info
+		obj, action, iobj = cmdtuple
+		# TRANS: When an error occurs in an action to be carried out,
+		# TRANS: then this is the heading of the error notification
+		return uiutils.show_notification(
+				_("Could not to carry out '%s'") % action,
+				unicode(value))
+
 	def run(self, obj, action, iobj, delegate=False):
 		"""
 		Activate the command (obj, action, iobj), where @iobj may be None
@@ -160,8 +185,9 @@ class ActionExecutionContext (gobject.GObject, pretty.OutputMixin):
 		if iobj is None and action.requires_object():
 			raise ActionExecutionError("%s requires indirect object" % action)
 
-		with self._nesting():
-			ret = activate_action(obj, action, iobj)
+		with self._error_conversion(obj, action, iobj):
+			with self._nesting():
+				ret = activate_action(obj, action, iobj)
 
 		# remember last command, but not delegated commands.
 		if not delegate:



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]