One way to do this (which is how I was thinking of implementing it) would be to introduce a 'try_sequence' which uses a 'catch' and 'finally' reference to subprocesses. This expression would inherit from the 'sequence' expression and redefine 'next_child' to replace the next children with the 'catch' sub-process if the previously evaluated child returned an error. The 'reply' would execute the 'finally' sub-process prior to returning to the parent.
<try_sequence catch='catch_process' finally='finally_process'> <participant ref='...'/> <participant ref='...'/> </try_sequence> <process-definition name="catch_process"> ... </process-definition> <process-definition name="finally_process"> ... </process-definition> Two comments: 1. It may also be good to introduce a 'try_concurrence' for completeness (I don't have a use case for it right now though) 2. Instead of introducing new expressions, the existing 'sequence' and 'concurrence' expressions could be modified to take these optional 'catch' and 'finally' parameters. Does this make sense? -- Raphael. Note that with this solution all the children of a 'sequence' expression inside a 'try_sequence' would get executed even if they failed which can be useful. On Tue, Nov 25, 2008 at 8:41 PM, John Mettraux <[EMAIL PROTECTED]>wrote: > > On Wed, Nov 26, 2008 at 12:55 PM, Raphael Simon <[EMAIL PROTECTED]> > wrote: > > > >> Another technique would be to wrap participants in subprocesses so > >> that you have participant + its exception handling stacked together. > >> > >> There are two kinds of subprocesses, the ones found in the main > >> process definition [document] and the external ones (usually called > >> via their URL or via their name (bound at the engine level), URL > >> accessed one are probably easier to manage). > > > > This would probably be better indeed but I'm still uncomfortable with the > > amount of duplication. > > OK, understood, > > > > I really appreciate your help, it's great to see you being so proactive. > > Another solution I was thinking about would be to have that __failed__ > field > > like you suggested but have each participant check for it. If it's there > the > > participant simply returns the workflow item right away without doing any > > work until it reaches an error handling participant. Thinking about it > > though it seems I would be just implementing a try/catch/finally > expression. > > So is there a fundamental reason why we can't or shouldn't have such an > > expression? I have been toying with the idea of implementing it myself > but I > > would like to get your opinion first. > > I have to admit I went without a try/catch mechanism and I was pushing > the "happy path only" approach. The java version of OpenWFE had an > "else-ref" attribute for participant that I still haven't ported to > Ruby (http://www.openwfe.org/manual/ch06s02.html#expression_participant), > but I guess it's not exactly what you're looking for. The idea is that > if the "ref" participant fails, the "else-ref" participant are tried > in order. > > There is also the undo/redo pair > (http://openwferu.rubyforge.org/expressions.html#exp_redo > http://openwferu.rubyforge.org/expressions.html#exp_undo) that > leverages "tag" attributes. It's possible to call 'undo' from inside a > tagged 'block' ( > http://github.com/jmettraux/ruote/tree/r0.9.19/test%2Fft_38_tag.rb#L105-123 > ). > This undo/redo mechanism could be leveraged to get a try/catch system. > > One could think of combining else-ref with undo, <participant > ref="unstable_one" else="undo" /> or something like that. > > Or we could simply go on and implement a "try" expression (with two > children expression) > > <try> > <sequence> > <!-- normal... --> > </sequence> > <sequence> > <!-- optional catch block... --> > </sequence> > <sequence> > <!-- optional finally block... --> > </sequence> > </try> > > But wait, error propagation would be a bit hard to have. How could the > error deep inside the normal path tell the try expression to cancel > its branch and switch to the catch/finally blocks... > > I have to think a bit more about all of this, maybe those hints given > here will give you a better idea. Maybe the else-ref mechanism would > be sufficient for you. Don't hesitate to paste or link to pieces of > processes (gist is great, http://gist.github.com/26859). I'm sure we > can find something that cuts down the amount of code required for > describing your processes. > > > Best regards, thanks for your feedback, > > -- > John Mettraux - http://jmettraux.wordpress.com > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "OpenWFEru users" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/openwferu-users?hl=en -~----------~----~----~----~------~----~------~--~---
