jBPM所需要处理的是java异常、jBPM系统异常和自定义异常(自定义handler中的异常)。java异常不进行传播,会中断流程实例的执行。jBPM系统异常和自定义异常在异常源中若未进行处理,会沿其父层次结构传播,直到找到匹配的异常处理子。如果在流程中未找到匹配的异常处理子,则该异常为uncaught异常,uncaught异常一般抛给客户端。
异常传播和事件传播相似,对jBPM系统异常和自定义异常,其异常传播树定义如下:
¨ 对于PDL节点(node)实例N和直接包含于其中的定时器(timer或monitor-timer)实例T,在异常传播树中,N是T的父节点。
¨ 对于PDL任务(task)实例T和包含于其中的监视定时器(monitor-timer)实例MT,在异常传播树中,T是MT的父节点。
¨ 对于PDL节点(node)实例N和直接包含于其中的事件响应(event-response)实例E,在异常传播树中,N是E的父节点。
¨ 对于PDL流程模板(template)实例T和包含于其中的事件定义(event-definition)实例E,在异常传播树中,T是E的父节点。
¨ 对于PDL任务(task)实例T和包含于其中的事件响应(event-response)实例E,在异常传播树中,T是E的父节点。
¨ 对于PDL迁移(transition)实例T,在异常传播树中,T的父节点的确定过程如下:
对T的源节点SN对应的父层次结构(包括N)以从子到父的顺序进行遍历,在遍历过程中,嵌套对T的目的节点DN的父层次结构进行相同顺序的遍历,在遍历过程中找到的第一个SN和DN的共同父节点是T的父节点。
¨ 对于PDL节点(node)实例N和包含于其中的任务(task)实例T,在异常传播树中,N是T的父节点。
¨ 对于PDL超节点(super-node)实例S和直接包含于其中的节点(node)实例N,在异常传播树中,S是N的父节点。
¨ 对于PDL流程模板(template)实例T和直接包含于其中的节点(node)实例N,在异常传播树中,T是N的父节点。
¨ 对于PDL过程节点(process-node)实例P和直接包含于该过程节点的“sub-process”元素所指称的流程模板中的节点(node)实例N,在异常传播树中,P是N的父节点。
按照如下方法确定异常传播源:
¨ DecisionHandler实例抛出的异常其异常源为DecisionHandler所在route-node。
¨ ActionHandler(script)实例抛出的异常其异常源为直接包含该action(scipt)的元素(可以是以下元素:template、node、transition、timer、monitor-timer、vent-definition或event-response)。
¨ AssignmentHandler实例抛出的异常其异常源为需要分派的任务(task)。
¨ VariablesMapHandler实例抛出的异常其异常源为需要进行变量映射的任务(task)或过程节点(process-node)。
¨ 其它异常的异常源为抛出异常的方法所在的元素(同ActionHandler)。
可以在流程模板(template)、节点(node)、迁移(transition)、事件定义(event-definition)、事件响应(event-response)、定时器(timer)、监视定时器(monitor-timer)以及任务(task)中指定exception-handler列表。每个exception-hanlder有一个action列表。当发生异常时,会在流程元素中沿其异常传播树搜索匹配异常类型的exception-handler。若找到相应的exception-handler,则执行其所有action。如果在流程实例中没有找到相应的exception-handler,则该异常为uncaught exception。uncaught exception一般被抛给客户端。异常处理完后,有四种可供选择的退出方法:
¨ Rollback:回退抛出异常时活跃的事务;
¨ Stop:停止流程的执行,不再处理任何剩余动作,即取消流程实例的执行;
¨ Retry:流程从抛出异常的动作重新开始执行,即重试出错的动作;
¨ Continue:流程从抛出异常的动作的下个动作开始执行。