Sitecore 10.2关联项发布遇断引用失败,求跳过配置方案
Sitecore 10.2 发布关联项时因断引用触发空引用错误,如何跳过或优化?
我有一个Sitecore 10.2站点,发布关联项时偶尔会触发空引用错误,原因是项存在断引用。目前发布直接失败,且未给内容作者提供有效提示,体验很差。我已经配置了Publishing.DeepScanRelatedItems = false,但问题依然存在。
错误日志如下:
Job started: Publish to 'web'|#Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object. at Sitecore.ContentTesting.Data.SitecoreContentTestStore.GetTestVariableID(RenderingReference reference) at Sitecore.ContentTesting.Data.SitecoreContentTestStore.GetMultivariateTestVariable(RenderingReference reference, Language language) at Sitecore.XA.Foundation.XConnect.Integration.Services.ContentTestingService.GetDatasources(RenderingReference rendering, Language language) at Sitecore.XA.Foundation.Publication.Pipelines.GetItemReferences.AddReferencedItemsToQueue.AddRenderingDataSourceReferences(Item item, PublishOptions options) at Sitecore.XA.Foundation.Publication.Pipelines.GetItemReferences.AddReferencedItemsToQueue.GetReferencedItems(PublishItemContext context) at Sitecore.XA.Foundation.Publication.Pipelines.GetItemReferences.AddReferencedItemsToQueue.GetItemReferences(PublishItemContext context) at Sitecore.Publishing.Pipelines.GetItemReferences.GetItemReferencesProcessor.Process(PublishItemContext context) at (Object , Object ) at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain, Boolean failIfNotExists) at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, Boolean failIfNotExists) at Sitecore.Publishing.Pipelines.GetItemReferences.GetItemReferencesPipeline.Run(PublishItemContext context, Boolean failIfNotExists) at (Object , Object ) at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain, Boolean failIfNotExists) at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain) at Sitecore.Publishing.Pipelines.PublishItem.PublishItemPipeline.Run(PublishItemContext context) at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessPublishingCandidate(PublishingCandidate entry, PublishContext context, List`1& referrers, List`1& children) at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessPublishingCandidate(PublishingCandidate entry, PublishContext context) at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessEntries(IEnumerable`1 entries, PublishContext context) at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessPublishingCandidate(PublishingCandidate entry, PublishContext context) at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessEntries(IEnumerable`1 entries, PublishContext context) at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.ProcessEntries(PublishContext context) at Sitecore.Publishing.Pipelines.Publish.ProcessQueue.Process(PublishContext context) at (Object , Object ) at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain, Boolean failIfNotExists) at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain) at Sitecore.Publishing.Pipelines.Publish.PublishPipeline.Run(PublishContext context) at Sitecore.Publishing.Publisher.PublishWithResult() --- End of inner exception stack trace --- at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at Sitecore.Reflection.ReflectionUtil.InvokeMethod(MethodInfo method, Object[] parameters, Object obj) at Sitecore.Jobs.JobRunner.RunMethod(JobArgs args) at (Object , Object ) at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain, Boolean failIfNotExists) at Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain) at Sitecore.Jobs.DefaultJob.DoExecute() at Sitecore.Abstractions.BaseJob.ThreadEntry(Object state)
我查过官方文档和日志,未找到解决方案。
解决方案
1. 自定义处理器包装XA关联项扫描逻辑,添加空值检查
错误根源是Sitecore.XA.Foundation.Publication.Pipelines.GetItemReferences.AddReferencedItemsToQueue处理器处理测试渲染引用时遇到空对象。可以创建自定义处理器包装原逻辑,添加异常捕获避免发布中断:
using Sitecore.Publishing.Pipelines.GetItemReferences; using Sitecore.XA.Foundation.Publication.Pipelines.GetItemReferences; public class SafeAddReferencedItemsToQueue : GetItemReferencesProcessor { private readonly AddReferencedItemsToQueue _originalProcessor = new AddReferencedItemsToQueue(); public override void Process(PublishItemContext context) { try { _originalProcessor.Process(context); } catch (NullReferenceException ex) { // 记录警告日志,不终止发布流程 Sitecore.Diagnostics.Log.Warn($"跳过发布中遇到的断引用,关联项ID:{context.Item?.ID}", ex, this); } } }
在App_Config/Include/YourProject目录下创建配置文件,替换原处理器:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> <sitecore> <pipelines> <getItemReferences> <processor type="Sitecore.XA.Foundation.Publication.Pipelines.GetItemReferences.AddReferencedItemsToQueue, Sitecore.XA.Foundation.Publication" patch:delete="true"/> <processor type="YourNamespace.SafeAddReferencedItemsToQueue, YourAssembly"/> </getItemReferences> </pipelines> </sitecore> </configuration>
2. 直接禁用XA的关联项扫描处理器
如果不需要XA的关联项扫描功能,可直接移除该处理器,从根源避免错误触发:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> <sitecore> <pipelines> <getItemReferences> <processor type="Sitecore.XA.Foundation.Publication.Pipelines.GetItemReferences.AddReferencedItemsToQueue, Sitecore.XA.Foundation.Publication" patch:delete="true"/> </getItemReferences> </pipelines> </sitecore> </configuration>
3. 自定义发布项过滤逻辑,跳过无效引用
通过publishItem管线添加处理器,提前过滤掉不存在的关联项:
using Sitecore.Publishing.Pipelines.PublishItem; public class SkipBrokenReferences : PublishItemProcessor { public override void Process(PublishItemContext context) { if (context.Item == null || context.PublishHelper.GetSourceItem(context.Item.ID, context.Language) == null) { context.Skip = true; Sitecore.Diagnostics.Log.Info($"发布时跳过无效引用项:{context.Item?.ID}", this); } } }
配置文件中添加该处理器到publishItem管线:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> <sitecore> <pipelines> <publishItem> <processor type="YourNamespace.SkipBrokenReferences, YourAssembly" patch:before="processor[@type='Sitecore.Publishing.Pipelines.PublishItem.CheckSecurity, Sitecore.Kernel']"/> </publishItem> </pipelines> </sitecore> </configuration>
4. 给内容作者添加断引用前置检测
从根源减少问题发生,可通过以下方式优化作者体验:
- 利用
ItemSaved事件,在保存项时自动检查关联项是否存在,若不存在弹出提示。 - 开发自定义Sitecore报表,定期扫描所有项的
RenderingReference字段,找出指向不存在项的引用并通知作者。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

