Hello,

I'm currently working to implement an error handling feature in a workflow.
I experimented with the :on_error statement and it seems to do its job
pretty well.
http://ruote.rubyforge.org/common_attributes.html#on_error

My workflow can crash essentially for three reasons:

1. a pre/post-condition is missing (I'll probably open a new thread about
this. let's ignore this case for now).
2. the person in charge of a workitem is not available (we currently compute
the assignee list internally of a participant)
3. anything else, including (but not limited to) Ruby syntax error, business
errors, etc.

Case 2 and 3 should have a different handling logic. For instance, in case
of a missing assignee the system should notify the HR team while in case of
a technical error the system should notify the Dev team. Also, the actions
required to solve the issue can vary.

After reading the documentation I came up with a possible solution but I
haven't been able to make it working. I'd like to know if it is the right
way or is there a better way to accomplish the task.

Basically, the difference between the case 2 and case 3 is the type of
exception. In case of PositionNotFound error, we're dealing with a case 2.
Otherwise, it's a case 3.

 My idea was to create two different participant classes and register both
rescuers as "rescue".

    class Case2ErrorRescuer < LocalParticipant
      def consume(workitem)
      end
      def accept?(workitem)
        puts "refusing #{workitem.sid}"
        workitem.error["class"] == "StandardError"
      end
    end
    class Case3ErrorRescuer < LocalParticipant
      def consume(workitem)
      end
      def accept?(workitem)
        puts "refusing #{workitem.sid}"
        workitem.error["class"] != "StandardError"
      end
    end

    $engine.register do
      ...
      participant /rescuer/, Case2ErrorRescuer
      participant /rescuer/, Case3ErrorRescuer
    end
    $engine.on_error = "rescuer"

As you can see, I'm using the accept? participant method to refuse a
workitem if the workitem doesn't satisfy the rescuer requirements.

The first part seems to work correctly. The Case3ErrorRescuer catches the
error, refuses it but then Ruote can't find the second participant.

Here's a piece of the Ruote log

    3 20       er * 20110331-yabizage 53c12 0_0_1
      20110331-yabizage StandardError
      20110331-yabizage kaboom
      20110331-yabizage on_reply.rb:43:in `consume'
      20110331-yabizage
/Users/weppos/.rvm/gems/ruby-1.9.2-p0/gems/ruote-2.2.0/lib/ruote/svc/dispatch_pool.rb:94:in
`do_dispatch'
      20110331-yabizage
/Users/weppos/.rvm/gems/ruby-1.9.2-p0/gems/ruote-2.2.0/lib/ruote/svc/dispatch_pool.rb:80:in
`dispatch'
      20110331-yabizage
/Users/weppos/.rvm/gems/ruby-1.9.2-p0/gems/ruote-2.2.0/lib/ruote/svc/dispatch_pool.rb:46:in
`handle'
      20110331-yabizage
/Users/weppos/.rvm/gems/ruby-1.9.2-p0/gems/ruote-2.2.0/lib/ruote/worker.rb:251:in
`process'
      20110331-yabizage
/Users/weppos/.rvm/gems/ruby-1.9.2-p0/gems/ruote-2.2.0/lib/ruote/worker.rb:173:in
`step'
      20110331-yabizage
/Users/weppos/.rvm/gems/ruby-1.9.2-p0/gems/ruote-2.2.0/lib/ruote/worker.rb:75:in
`run'
      20110331-yabizage
/Users/weppos/.rvm/gems/ruby-1.9.2-p0/gems/ruote-2.2.0/lib/ruote/worker.rb:87:in
`block in run_in_thread'
    4 20 la * 20110331-yabizage
{:wi=>["0!e19bad339b60cc51e8e26dbc65627f39!20110331-yabizage", 3],
:t=>["define", {}, [["rescuer", {}, []]]]}
    refusing 0_0!adeb3818be3bee055ab8ea5a7a6a0eae!20110331-yabizage
    5 20     er * 20110331-yabizage adeb3 0_0
      20110331-yabizage RuntimeError
      20110331-yabizage unknown participant or subprocess 'rescuer'
      20110331-yabizage
/Users/weppos/.rvm/gems/ruby-1.9.2-p0/gems/ruote-2.2.0/lib/ruote/exp/fe_ref.rb:90:in
`apply'
      20110331-yabizage
/Users/weppos/.rvm/gems/ruby-1.9.2-p0/gems/ruote-2.2.0/lib/ruote/exp/flowexpression.rb:253:in
`do_apply'
      20110331-yabizage
/Users/weppos/.rvm/gems/ruby-1.9.2-p0/gems/ruote-2.2.0/lib/ruote/worker.rb:326:in
`launch'
      20110331-yabizage
/Users/weppos/.rvm/gems/ruby-1.9.2-p0/gems/ruote-2.2.0/lib/ruote/worker.rb:243:in
`process'
      20110331-yabizage
/Users/weppos/.rvm/gems/ruby-1.9.2-p0/gems/ruote-2.2.0/lib/ruote/worker.rb:173:in
`step'
      20110331-yabizage
/Users/weppos/.rvm/gems/ruby-1.9.2-p0/gems/ruote-2.2.0/lib/ruote/worker.rb:75:in
`run'
      20110331-yabizage
/Users/weppos/.rvm/gems/ruby-1.9.2-p0/gems/ruote-2.2.0/lib/ruote/worker.rb:87:in
`block in run_in_thread'

I believe one alternative would be to create a subprocess with a sequence
and append several :if conditions in the subprocess definition to filter
according to the value of the __error__ field, but this solution is quite
complex and not very flexible because limited by the workflow DSL.

Is there a better way to accomplish this task? Something similar to the
Rails rescue_from feature.
http://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html

Thanks,
-- Simone


-- 
Simone Carletti
Application Developer

Site & Blog: http://www.simonecarletti.com
Email: [email protected]
LinkedIn: http://linkedin.com/in/weppos
Skype: weppos

-- 
you received this message because you are subscribed to the "ruote users" group.
to post : send email to [email protected]
to unsubscribe : send email to [email protected]
more options : http://groups.google.com/group/openwferu-users?hl=en

Reply via email to