
- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 04-06-2020 10:44 AM
Premise
I've been debugging some... less than stable Business rules recently and came across an interesting question: What happens if a Before business rule crashes?
Diving Deeper
For those of you who are unfamiliar, Before business rules behave slightly differently from the other stages. Per the documentation: "Changes made in before business rules are automatically saved when all before business rules are complete". But how exactly is that implemented? What happens if a BR crashes mid-step? Is the entire step cancelled, preventing the batch update? Or perhaps the offending BR is ignored and its changes discarded?
How Before Business Rules Operate, Simplified
After a bit of digging, what I've found, behavior-wise, is something like this:
// Not the actual code behind the scenes, but this should illustrate what's going on
var businessRules = getBusinessRules(targetRecord);
var previous = getPrevious(targetRecord);
// Current is a shared global variable between all BRs in the before execution phase
var current = gr.get(targetRecord);
// Run each rule as far as possible, log BR crashes, but do no cleanup
businessRules.forEach(function(businessRuleFn){
try {
businessRuleFn(current, previous);
} catch(e) {
gs.addErrorMessage(e);
}
});
// Run update once using the changes to the shared current object
current.setWorkflow(false);
current.update();
// This means that script outcome (crash or no crash) is ignored, granted the crashing script managed to mutate current prior to crashing
In Other Words
- A crashing Business Rule will not prevent other business rules from applying
- The current object passed to the Business rule is a single shared object. There's no real boundaries here, so cleanup isn't a consideration.
- Because there's no cleanup when an individual BR crashes, any changes that the BR is able to stick onto current prior to crashing will persist, regardless of the fact that it crashed.
Example Scenario A: Early Crash
Let's say we crash immediately, what happens?
BR Script
(function executeRule(current, previous /*null when async*/) {
throw new Error();
current.foo = 'FOO';
current.bar = 'BAR';
})(current, previous);
Result
Somewhat obviously, nothing happens. We crash so early that current is never modified! Of course, as previously mentioned, all other Business Rules continue on working as expected, regardless of what happens in this one individual script. An uncaught error in a business rule script will never prevent the final batch update in the before business rule step from running.
Example Scenario B: Mid-Way Crash
But what happens if we crash mid-way?
BR Script
(function executeRule(current, previous /*null when async*/) {
current.foo = 'FOO';
throw new Error();
current.bar = 'BAR';
})(current, previous);
Result
In this case, current.foo is set to 'FOO'! This is because current is a shared object: At the end of the day, the before business rule step only cares about the final state of current, not how we got there. Of course, current.bar remains undefined, because we crashed out prior to reaching that step.
- 940 Views