Process Failure Rules
As explained in the previous sections when a rule issues the REPORT ERROR action the execution of the current request is terminated and the current transaction is rolled back. However, what about the situations when we do not want this to happen? Consider, for example, the following scenario. We have a banking system and we want to define a process that would be scheduled to run overnight to find all pending fund transfers and execute them. Some of the fund transfers may fail (for example, there may be not enough funds in the bank account from which the transfer is made). Our process may look something like this:
FIND FundsTransfer WHERE FundsTransfer.State = 'READY'
FundsTransfer.State = 'APPLIED'
The first rule finds all the pending transfers and the second one executes them. Let us assume that the FundsTransfer
object has the following validation rule, which checks that there are enough funds:
IF FundsTransfer.State WAS CHANGED TO 'APPLIED' AND FundsTransfer.Amount > FundsTranfer.FromAccount.Balance THEN REPORT ERROR 'Not enough funds in the account for transfer operation'
If our process encounters a transfer with insufficient funds and tries to change its state to APPLIED
the above validation rule will be triggered. The problem is that this rule will abort the current transaction and the entire process will be terminated. What we want, though, is not to terminate the current process, but make the appropriate record about the failed transfer and continue execution of the process. One way to solve the problem would be to change the validation rule, so that instead of reporting an error it would set the state of the transfer to FAILED
, for example:
IF FundsTransfer.State WAS CHANGED TO 'APPLIED' AND FundsTransfer.Amount > FundsTranfer.FromAccount.Balance THEN FundsTransfer.State = 'Failed'
This solution may be valid in some situations; however, the main problem with it is that it makes rules of the object dependent on the context in which the object is used. For example, when setting the state to FAILED
in the rule above we make an assumption that the object will be used within the context of the scheduled process and this is the reason why we are setting the state rather than reporting the error. What if the object is used in other contexts – for example, a user sets the state of the transfer manually on the object form?
The recommended solution to the above problem is to define process failure rules. These rules may be attached to a process and they will be executed whenever the process fails as a result of the execution of the REPORT ERROR
action anywhere during the course of the process. Failure rules are supposed to perform corrective actions to neutralize the effects of the failure. Most importantly, if failure rules are defined for a process, execution of the process continues after failure and the current transaction is not rolled back (unless failure rules themselves report an error). The sequence is as follows:
- A process starts executing
- A failure occurs by rules of any object affected by the process issuing the
REPORT ERROR
action. - If process failure rules are not defined, the execution of the current request is terminated and the transaction is rolled back. If process failure rules are defined they start executing and performing corrective actions.
- Process execution continues as if there was no failure.
In our example we could define the failure rules as follows:
FailedFundsTransfer.State = 'FAILED' FailedFundsTrasfer.FailureReason = ProcessError.Message
If we define process failure rules like shown above we can still leave the REPORT ERROR
action in the validation rule of the FundsTransfer
object.
Note the usage of the special Failed
prefix in front of the FundsTransfer
object. This prefix can be used to distinguish the instance of the FundsTransfer
object that caused the failure from all other instances of the FundsTransfer
object (see also Instance Prefixes). In fact, all objects that were involved in the failed operation are placed in the Context and are accessible via the Failed
prefix – for example, if in response to changing its state to APPLIED
the FundsTransfer
object created or modified another object, which created or modified yet another object the rules of which issued the REPORT ERROR
action, all these objects are written into the Context and are available to process failure rules. If there can only be one instance of a particular object it can also be accessed by the failure rules without the Failed prefix.
Note also the usage of a special predefined object called ProcessError
. The instance of this object is automatically created by the system for the process failure rules to use (it is not available to any other rules). The attributes of this object are explained in the following table:
Attribute name | Comments |
---|---|
Message | Error message issued by the REPORT ERROR action that caused the failure |
FailedObject | The name of the business object the rules of which issued the REPORT ERROR action |
FailedRuleName | The name of the rule that issued the REPORT ERROR action |
FailedRule | The text of the rule that issued the REPORT ERROR action |
CurrentObject | The name of the business object used directly by the process, the modification or creation of which ultimately caused the REPORT ERROR action (can be UNDEFINED or can be the same as FailedObject) |
CurrentRuleName | The name of the rule inside the process that the process was executing when the failure occurred. |
CurrentRule | The text of the rule inside the process that the process was executing when the failure occurred. |
note
Process failure rules are also executed if a process has been cancelled by the user. For example, if a process callsENTER NEW
action the form of the object will be shown to the user. If the user clicks on the Cancel button on the form, the process will be cancelled and the failure rules (if any) will be activated. In this case no special predefined object describing the failure is written into the context.