What happened was a client site had Commerce running with a custom customer profile type defined in code. However, they had deleted (or through their development workflow prevented) the customer profile reference field that Commerce Order expects to be added to the order object. This is fine, since it's not a locked field... it should be deletable. However, I had a default Rule that dealt with updating referenced profiles when an order completes checkout that expected that field to be present.

This isn't such a big deal, because it's easy to fix through the UI. I added a new customer profile reference field to the order type and updated the Rule so that it pointed to that field instead of the default one (i.e. update commerce-order:field-contact-information instead of commerce-order:commerce-customer-contact-information). By appearances it should have worked just fine, but when I displayed the Rules log messages, I realized that the stupid thing was never being evaluated. It wasn't that its conditions weren't passing, it's just that Rules when loading the various Rules for an event just totally skipped this one (and one other like it).

The only way I could get it to recognize them was to revert the Rules, fix the code so that the default Rule didn't include a reference to the non-existent field, and then re-add my custom action to manipulate the proper profile. So in the end, the Rule that was actually getting executed was exactly the same, but the default Rule did not include the invalid field reference.

It seems, therefore, that the root of the problem is as the title describes: an invalid default Rule will not be loaded for evaluation when invoking an event it's attached to, even if said Rule has been fixed via the UI.

CommentFileSizeAuthor
#7 rules_fix_dirty.patch7.99 KBfago
#4 rules_fix_dirty.patch6.34 KBfago
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

fago’s picture

Title: Invalid default Rules aren't evaluated even if they've been fixed via the UI » Rules remain dirty even if they've been fixed via the UI
Component: Rules Core » Rules Engine

yep, we are missing a proper logic for setting dirty rules back to clean. As of now that's only done if a previously missing module is enabled, but as you describe very well we need to do so in other situations too, e.g. when saving a rule.

Also, the UI currently does not really show whether a Rule is dirty if it actually isn't any more, i.e. now exception is thrown. That's suboptimal too.

dasjo’s picture

my rules don't seem to be dirty, but they are :) (subscribing from #1269824: Check dirty rules on save)

fago’s picture

fago’s picture

Status: Active » Needs review
FileSize
6.34 KB

ok, here is a patch which fixes it for me.

Changes:
* always check all rules on cache-clear, including dirty ones and update the dirty status if necessary. That way rules that are clean will be accordingly updated an used again.
* do the same dirty flag update before saving a rule
* added a watchdog message that notifies user when a rule is working again

dasjo’s picture

using the patch, my rule worked again after saving.

without saving, it didn't list any errors but failed to execute

• 0 ms Executing action rule: MyRulesComponent.
• 0.664 ms Evaluating the action my_rules_compoenent. [edit]
• 2.826 ms Unable to get the component my_rules_compoenent

fago’s picture

Priority: Normal » Critical
Status: Needs review » Fixed

Yep, the dirty flag is re-set upon cache-clear or upon saving, what should already greatly improve things. However, there is still a situation where one could end up with a dirty, but already working rule, e.g. via changing fields what doesn't issue a full-cache clear.

Thus, I've improved the display of rules to handle this case too and re-enables the rule then + shows a message.

As this is a rather critical issue, I've gone ahead and committed the patch attached, please test!
Let's do any remarks improvements as follow-up.

fago’s picture

FileSize
7.99 KB

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.