开发者

Doing a raise while Products.CMFCore.interfaces.IActionSucceededEvent is being executed is going to abort the ZODB transaction for the workflow?

Suppose I have mynamespace.myproduct:

 <subscriber for="..interfaces.myinterface.IMyInterface
                  Products.CMFCore.interfaces.IActionSucceededEvent" 
            handler=".handlers.actionSucceeded" 
    /> 

and mynamespace.myproduct2:

 <subscriber for="..interfaces.myinterface.IMyInterface
                  Products.CMFCore.interfaces.IActionSucceededEvent" 
            handler=".handlers.actionSucceeded" 
    /> 

(the handlers do different stuff, on each product, even if they have the same name on this example)

I have a custom type that has a custom workflow. I'm going to do a workflow transition from Python, using doActionFor, and do a bunch of things when IActionSucceededEvent is triggered.

My question is: if I raise an exception on any of .handlers.actionSucceeded if an error occurs, will the doActionFor call be reverted (even after IActionSucceededEvent was run)? If not, if I use IActionWillBeInvokedEvent, will I be able to accomplish my goals? Will I have a problem for having two different products, both using Products.CMF开发者_运维百科Core.interfaces.IActionSucceededEvent for the same ..interfaces.myinterface.IMyInterface interface?


  1. Yes, if you raise any exception in one of your handlers the entire transaction will fail and it will be reverted
  2. no, you wouldn't have problems using more than one subscriber for the same interfaces. They would be execute in order of registration.
  3. no, using IActionWillBeInvokedEvent will not help. It's fired before wf transition, but if you raise exceptions the transaction will fail anyway.


You can check this by turning Plone debug level to DEBUG (default is info) and put logging output to the event handlers. In DEBUG logging Plone prints transaction boundaries.

If your exception causes "505 Internal Server error" when the exception is raised it will also unroll any on-going transaction (unless transaction.commit() is called manually, but that should not be the case for the normal code).


As per @Giacomo's response, the transaction will be aborted for any exception that isn't caught. So your best bet is to find out what errors you want to tolerate and catch those exceptions in your subscriber, log the exception, and then move on so the transaction will still be committed:

import logging
logger = logging.getLogger('mynamespace.myproduct')
...
def actionSucceeded(obj, event):
    ...
    try:
        my_dangerous_stuff(...)
    except (TolerableException, AnotherTolerableException, ...):
        logger.exception('Encountered an error while handling foo event')
    ...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜