Uh oh.
The following errors are heavily present on my client's content delivery servers:
ERROR Evaluation of condition failed. Rule item ID:
Unknown, condition item ID: {9A4BEB4B-4B0F-4392-A798-124CEC8AADA4}Exception: Sitecore.Framework.Conditions.PostconditionException
Message: Postcondition 'Tracker.Current.Session.Interaction should not be null' failed.at Sitecore.Framework.Conditions.EnsuresValidator`1.ThrowExceptionCore(String condition, String additionalMessage, ConstraintViolationType type)
Source: Sitecore.Framework.Conditions
at Sitecore.Framework.Conditions.Throw.ValueShouldNotBeNull[T](ConditionValidator`1 validator, String conditionDescription)
at Sitecore.Framework.Conditions.ValidatorExtensions.IsNotNull[T](ConditionValidator`1 validator)
at Sitecore.ContentTesting.Rules.Conditions.CountryCondition`1.Execute(T ruleContext)
at Sitecore.Rules.Conditions.WhenCondition`1.Evaluate(T ruleContext, RuleStack stack)
at Sitecore.Rules.Conditions.OrCondition`1.Evaluate(T ruleContext, RuleStack stack)
at Sitecore.Rules.Conditions.WhenRule`1.Execute(T ruleContext)
at Sitecore.Rules.Conditions.WhenCondition`1.Evaluate(T ruleContext, RuleStack stack)
at Sitecore.Rules.RuleList`1.Run(T ruleContext, Boolean stopOnFirstMatching, Int32& executedRulesCount)
We're talking thousands upon thousands of these errors.
The error references a GUID we can use to determine the context of this:
{9A4BEB4B-4B0F-4392-A798-124CEC8AADA4}Moreover, the error's message hints are what ultimately causes the error to trigger:
Tracker.Current.Session.Interaction should not be null
For context, the GUID refers to the following out-of-the-box Sitecore item:
/sitecore/system/Settings/Rules/Definitions/Elements/Predefined Rules/Predefined Rule
Nothing to see here... |
After digging in, I found that the client had configured personalization on a Controller Rendering for their site's homepage component rendering so that depending on the user’s country, unique content is presented. They've implemented the following Predefined rules on the rendering:
- visitor is located in the Asia Pacific region- visitor is located in the UK- or where visitor is equal to the United Kingdom- where visitor is located in Continental Europe
These are custom rules they've added that categorize a list of countries into a region they want to target.
For example, the `visitor is located in the Asia Pacific region` looks like this:
where the country is equal to Australiaor where the country is equal to Brunei Darussalamor where the country is equal to Chinaor where the country is equal to Hong Kongor where the country is equal to Singaporeor where the country is equal to Taiwanor where the country is equal to Thailandor where the country is equal to New Zealandor where the country is equal to Qataror where the country is equal to Turkeyor where the country is equal to Malaysiaor where the country is equal to Russian Federationor where the country is equal to Indiaor where the country is equal to Indonesiaor where the country is equal to United Arab Emiratesor where the country is equal to Philippinesor where the country is equal to Israelor where the country is equal to Pakistanor where the country is equal to Saudi Arabiaor where the country is equal to Vietnamor where the country is equal to Japan
Each country has been defined using the out-of-the-box `GeoIP` > `where the country compares to specific countries` condition template.
This line in the error denotes that the `CountryCondition` is the culprit in regards to the recurring error:
at Sitecore.ContentTesting.Rules.Conditions.CountryCondition`1.Execute(T ruleContext)
According to a reflection of the `Sitecore.ContentTesting.Rules.Conditions` namespace in Sitecore.ContentTesting.dll for v10.0.0, this series of checks in the first few lines of the `CountryCondition<T> : VisitCondition<T> where T : RuleContext` class's Execute() method:
My hunch was that the last check was causing the failure, and instead of failing silently, it throws an error - specifically often in cases where bot-like traffic is involved.
Condition.Ensures<CurrentInteraction>(Tracker.Current.Session.Interaction, "Tracker.Current.Session.Interaction").IsNotNull<CurrentInteraction>();
To quell the flood of errors initially, I applied a new stand-alone rule preceding each existing visitor is rule located in {REGION_NAME} region called `visitor is human` (also out-of-the-box) to attempt to deflect bots and spam where a country code or identifiable contact/interaction is unlikely to yield a country (which would result in an error):
After applying these changes and publishing them, we see those errors disappear entirely from the error logs. However, the introduction of the `visitor is human` rule proceeding the rest had an unintended effect: first-time visitors always failed this first condition, causing them to only see the personalized rendering after reloading the page. Removing the rule enabled users to receive the personalized rendering on the first load but reintroduced the flood of errors.
It seemed that instances where `Tracker.Current.Session.Interaction` is null may be caused by bot traffic according to: https://support.sitecore.com/kb?id=kb_article_view&sysparm_article=KB0960279
Given that this is version 10.0.0, this particular bug should have been resolved in all versions above 8.1.
Upon decompiling and comparing the GetTracker : CreateTrackerProcessor > Process() override in Sitecore.Support.424667.81.dll for v8.1+ to the 10.0.0 Sitecore.Analytics.dll's GetTracker : CreateTrackerProcessor > Process method, there's one notable difference:
v8.1+
v10.0.0
It was unclear if we need a similar patch to implement `args.set_Tracker(new DefaultTracker());` in the Process() method.
I raised the question with Sitecore Support to explore one of two resolutions:
1) A patch for suppressing errors in Sitecore.ContentTesting.Rules.Conditions.CountryCondition's Execute() method, when the `Condition.Ensures<CurrentInteraction>(Tracker.Current.Session.Interaction, "Tracker.Current.Session.Interaction").IsNotNull<CurrentInteraction>();` is not satisfied (perhaps by returning false).
or
2) An override patch for the tracker creation similar to the https://support.sitecore.com/kb?id=kb_article_view&sysparm_article=KB0960279 hotfix.
Sitecore Support was able to reproduce the reported behavior in a clean local instance of Sitecore 10.0.0 (Initial Release) without involving any of our specific customizations.
They registered the issue as a bug in their bug tracking system (future reference number 456739).
The reported behavior occurs because Sitecore.Rules.Conditions.WhenRule class inherits CanEvaluate() method from Sitecore.Rules.Conditions.RuleConditionclass which always returns true. That is why the rule is not skipped so the evaluation continues and leads to the exception.
In order to workaround the issue, please try to avoid the usage of Conditional renderings rules.
Please assign conditions to your renderings directly without wrapping them into conditional renderings rule.
In this case, Sitecore will trigger CanEvaluate method related to the specific condition, so the condition will be skipped.
I ended up pursuing the following approach myself:
- Decompiled the `Sitecore.ContentTesting.dll` and copied the Sitecore.ContentTesting.Rules.Conditions.CountryCondition class into our solution called `CountryConditionOverride`. I used Telerik JustDecompile for this.
- Commented the offending line (48) and replaced it with a simple null check that returns false.
- Enabled the custom override class by updating the `Type` field on the following default Sitecore item and published it:
/sitecore/system/Settings/Rules/Definitions/Elements/GeoIP/Country
{52E42C59-7210-43E5-94A6-3EA6B98835B8}
Field: Script (section) > Type
Old value: `Sitecore.ContentTesting.Rules.Conditions.CountryCondition,Sitecore.ContentTesting`
New value: `Foundation.Overrides.Rules.Conditions.CountryConditionOverride, Foundation.Overrides`
The final override class:
This resolves the issue with erroneous error log entries while retaining the expected Country condition functionality when the `Tracker.Current.Session.Interaction` happens to not be null.
I've shared my resolution with Sitecore Support and will keep an eye on an official hotfix (reference 456739), which I will share once it's available.
Hopefully, in the meantime, this helps someone out there in a similar scenario!
Thanks for sharing the details...
ReplyDelete