[Checkins] SVN: hurry.workflow/trunk/ More informative exceptions.

Martijn Faassen cvs-admin at zope.org
Thu Jan 17 15:25:28 UTC 2013


Log message for revision 129039:
  More informative exceptions.
  

Changed:
  U   hurry.workflow/trunk/CHANGES.txt
  U   hurry.workflow/trunk/src/hurry/workflow/interfaces.py
  U   hurry.workflow/trunk/src/hurry/workflow/workflow.py
  U   hurry.workflow/trunk/src/hurry/workflow/workflow.txt

-=-
Modified: hurry.workflow/trunk/CHANGES.txt
===================================================================
--- hurry.workflow/trunk/CHANGES.txt	2013-01-17 15:20:32 UTC (rev 129038)
+++ hurry.workflow/trunk/CHANGES.txt	2013-01-17 15:25:28 UTC (rev 129039)
@@ -5,9 +5,17 @@
 0.13 (unreleased)
 =================
 
-- Nothing changed yet.
+* ``NoTransitionAvailableError`` gained a ``source`` and ``destination``
+  attribute indicating what transition wasn't available.
 
+* ``AmbiguousTransitionError`` also gained a ``source`` and ``destination``
+  attribute indicating what transition was ambiguous.
+ 
+* ``InvalidTransitionError`` gained a ``source`` attribute indicating
+  the source state of the attempted invalid transition.
 
+* Newer ``bootstrap.py``
+
 0.12 (2012-02-10)
 =================
 

Modified: hurry.workflow/trunk/src/hurry/workflow/interfaces.py
===================================================================
--- hurry.workflow/trunk/src/hurry/workflow/interfaces.py	2013-01-17 15:20:32 UTC (rev 129038)
+++ hurry.workflow/trunk/src/hurry/workflow/interfaces.py	2013-01-17 15:25:28 UTC (rev 129039)
@@ -6,13 +6,18 @@
 SYSTEM = 2
 
 class InvalidTransitionError(Exception):
-    pass
+    def __init__(self, source):
+        self.source = source
 
 class NoTransitionAvailableError(InvalidTransitionError):
-    pass
-
+    def __init__(self, source, destination):
+        super(NoTransitionAvailableError, self).__init__(source)
+        self.destination = destination
+        
 class AmbiguousTransitionError(InvalidTransitionError):
-    pass
+    def __init__(self, source, destination):
+        super(AmbiguousTransitionError, self).__init__(source)
+        self.destination = destination
 
 class ConditionFailedError(Exception):
     pass

Modified: hurry.workflow/trunk/src/hurry/workflow/workflow.py
===================================================================
--- hurry.workflow/trunk/src/hurry/workflow/workflow.py	2013-01-17 15:20:32 UTC (rev 129038)
+++ hurry.workflow/trunk/src/hurry/workflow/workflow.py	2013-01-17 15:25:28 UTC (rev 129039)
@@ -84,7 +84,7 @@
     def getTransition(self, source, transition_id):
         transition = self._id_transitions[transition_id]
         if transition.source != source:
-            raise InvalidTransitionError
+            raise InvalidTransitionError(source)
         return transition
 
     def getTransitionById(self, transition_id):
@@ -159,6 +159,7 @@
                                transition.permission)
         # now make sure transition can still work in this context
         if not transition.condition(self, self.context):
+            # XXX should we include state info here? if so, what?
             raise ConditionFailedError
         # perform action, return any result as new version
         result = transition.action(self, self.context)
@@ -200,9 +201,13 @@
         transition_ids = self.getFireableTransitionIdsToward(state,
                                                              check_security)
         if not transition_ids:
-            raise interfaces.NoTransitionAvailableError
+            raise interfaces.NoTransitionAvailableError(
+                self.state(self.context).getState(),
+                state)
         if len(transition_ids) != 1:
-            raise interfaces.AmbiguousTransitionError
+            raise interfaces.AmbiguousTransitionError(
+                self.state(self.context).getState(),
+                state)
         return self.fireTransition(transition_ids[0],
                                    comment, side_effect, check_security)
 

Modified: hurry.workflow/trunk/src/hurry/workflow/workflow.txt
===================================================================
--- hurry.workflow/trunk/src/hurry/workflow/workflow.txt	2013-01-17 15:20:32 UTC (rev 129038)
+++ hurry.workflow/trunk/src/hurry/workflow/workflow.txt	2013-01-17 15:25:28 UTC (rev 129039)
@@ -98,6 +98,22 @@
     >>> from zope import component
     >>> component.provideUtility(wf, interfaces.IWorkflow)
 
+We can get the transition from the workflow using ``get_transition``
+should we need it::
+
+    >>> wf.getTransition('a', 'a_to_b') is transition
+    True
+
+If we try to get a transition that doesn't exist, we get an error::
+
+    >>> from hurry.workflow.interfaces import InvalidTransitionError
+    >>> try:
+    ...   wf.getTransition('b', 'a_to_b')
+    ... except InvalidTransitionError, e:
+    ...   pass
+    >>> e.source
+    'b'
+
 Workflow transitions cause events to be fired; we will put in a simple
 handler so we can check whether things were successfully fired::
 
@@ -169,6 +185,18 @@
     ...
     NoTransitionAvailableError
 
+This error has some information available of what transition was attempted::
+
+    >>> from hurry.workflow.interfaces import NoTransitionAvailableError
+    >>> try:
+    ...   info.fireTransitionToward('c')
+    ... except NoTransitionAvailableError, e:
+    ...   pass
+    >>> e.source
+    'a'
+    >>> e.destination
+    'c'
+
 Now go to 'b' again::
 
     >>> info.fireTransitionToward('b')
@@ -890,3 +918,48 @@
    2
    >>> events[1].object.title[-1] == '!'
    True
+
+Ambiguous transitions
+=====================
+
+Let's set up a situation where there are two equivalent transitions from
+``a`` to ``b``::
+
+    >>> transition1 = workflow.Transition(
+    ...     transition_id='a_to_b1',
+    ...     title='A to B',
+    ...     source='a',
+    ...     destination='b',
+    ...     condition=NullCondition,
+    ...     action=NullAction,
+    ...     trigger=interfaces.MANUAL)
+
+    >>> transition2 = workflow.Transition(
+    ...     transition_id='a_to_b2',
+    ...     title='A to B',
+    ...     source='a',
+    ...     destination='b',
+    ...     condition=NullCondition,
+    ...     action=NullAction,
+    ...     trigger=interfaces.MANUAL)
+
+
+    >>> wf = workflow.Workflow([transition1, transition2])
+    >>> from zope import component
+    >>> component.provideUtility(wf, interfaces.IWorkflow)
+    >>> info = interfaces.IWorkflowInfo(document)
+    >>> state = interfaces.IWorkflowState(document)
+    >>> state.setState('a')
+
+``fireTransitionToward`` is ambiguous as two transitions are possible::
+
+    >>> from hurry.workflow.interfaces import AmbiguousTransitionError
+    >>> try:
+    ...   info.fireTransitionToward('b')
+    ... except AmbiguousTransitionError, e:
+    ...   pass
+    >>> e.source
+    'a'
+    >>> e.destination
+    'b'
+



More information about the checkins mailing list