Server Error "Object reference not set to an instance of an object" after insert from branch

2k views Asked by At

Everything works correctly but after Sitecore update from 7.0 to 7.2 I see the following Server Error when creating a site from a branch

[NullReferenceException: Object reference not set to an instance of an object.]
   Sitecore.Nexus.Data.DataCommands.AddFromTemplateCommand.(Item , Item , String , ID , ID , String , SafeDictionary`2 ) +420
   Sitecore.Nexus.Data.DataCommands.AddFromTemplateCommand.(Item , Item , String , ID , ID , String , SafeDictionary`2 ) +856
   Sitecore.Nexus.Data.DataCommands.AddFromTemplateCommand.(String , Item , Item , ID ) +569
   Sitecore.Data.Engines.DataCommands.AddFromTemplateCommand.DoExecute() +113
   Sitecore.Data.Engines.EngineCommand`2.Execute() +121
   Sitecore.Data.Engines.DataEngine.AddFromTemplate(String itemName, ID templateId, Item destination, ID newId) +101
   Sitecore.Data.Managers.ItemProvider.AddFromTemplate(String itemName, ID templateId, Item destination, ID newId) +363
   Sitecore.Data.Managers.ItemManager.AddFromTemplate(String itemName, ID templateId, Item destination, ID newItemId) +203
   Sitecore.Data.Managers.ItemManager.AddFromTemplate(String itemName, ID templateId, Item destination) +286
   Sitecore.Data.Items.Item.Add(String name, BranchId branchId) +110
   Sitecore.Workflows.WorkflowContext.AddItem(String name, BranchItem branch, Item parent) +279
   Sitecore.Shell.Framework.Commands.AddMaster.Add(ClientPipelineArgs args) +803

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
   System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
   System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) +76
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +211
   System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) +35
   Sitecore.Nexus.Pipelines.NexusPipelineApi.Resume(PipelineArgs args, Pipeline pipeline) +398
   Sitecore.Web.UI.Sheer.ClientPage.ResumePipeline() +285
   Sitecore.Web.UI.Sheer.ClientPage.OnPreRender(EventArgs e) +547
   Sitecore.Shell.Applications.ContentManager.ContentEditorPage.OnPreRender(EventArgs e) +25
   System.Web.UI.Control.PreRenderRecursiveInternal() +113
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4297

A site creates correctly and I see no problems there.

As far as I see the error occurs in the item:addmaster command:

<command name="item:addmaster" type="Sitecore.Shell.Framework.Commands.AddMaster,Sitecore.Kernel" />

I have tried to decompile Sitecore.Nexus library but without any success. After some of hours of the investigation I found that the error disappears if turn off a custom event handler

<event name="item:created">
   <handler type="App.Client.Tasks.ItemEventHandler, App.Client" method="OnItemCreated" />
</event>

The handler is responsible for auto mapping configuration settings in a new site created from a branch. Technically there is an item in branch template called Mapper and it works as a trigger. It is the last item in the branch tree. So when an admin adds a site from a branch, event handler checks that the Mapper is created (in other words a site is created), runs auto mapping functionality and deletes the trigger.

If to omit all checks, the handler looks like

new ItemMappingManager(contextItem, Database.GetDatabase("master").Items[ID.Parse(MappingConfigurationItemId)]).Execute();

// delete the trigger item once the branch has been created and mapping is done
using (new SecurityDisabler())
{
    contextItem.Delete();
}

Looks like something changed in the Sitecore's event model but I have a lack of knowledge here.

1

There are 1 answers

0
Zachary Kniebel On

Try wrapping any calls to Sitecore.Data.Engines.DataEngine.AddFromTemplate or any calls that you are making that add an item with an EventDisabler. Because the exception is being thrown in Nexus, it's difficult to say what the exact cause of the issue is.

When I experienced a similar issue, I had a theory that there may have been some eventing that was firing and causing the exceptions. The error did not always occur, and it was difficult to find the cause of the error since it was being thrown in Nexus. While investigating and debugging as best I could (deobfuscated, decompiled and read through and debugged into Nexus), I found that there were several API calls being made that raise events (e.g. AddVersion, AddMaster, etc.). I considered my theory confirmed when the exception disappeared after I wrapped my code in an EventDisabler.

My Similar Experience

I just experienced nearly the same issue with Sitecore 8.1.2. The difference between my code and the code in the OP is that I am leveraging the new (I believe newer than the OP) ItemProvider via a processor that I have added to the AddFromTemplate pipeline.

The below is the processor that I added. I use this processor to run rules, and I was receiving the exact same error, until I wrapped my call to Sitecore.Data.Engines.DataEngine.AddFromTemplate (must be called or else the item never actually gets created) in an EventDisabler.

Processor Before Fix

        public override void Process([NotNull] AddFromTemplateArgs args)
        {
            ID id; 

            if (args.Aborted 
                || string.IsNullOrWhiteSpace(RuleFolderId) 
                || !Settings.Rules.ItemEventHandlers.RulesSupported(args.Destination.Database)
                || !ID.TryParse(RuleFolderId, out id))
            {
                return;
            }

            Assert.HasAccess(args.Destination.Access.CanCreate(), "You do not have permission to create items here.");

            // exception thrown from this call, which is a required call for this  
            //   processor, or else the item will not actually be created
            var item = args.Destination.Database.Engines.DataEngine.AddFromTemplate(
                args.ItemName,
                args.TemplateId,
                args.Destination,
                args.NewId);

            args.ProcessorItem = item;
            args.Result = item;

            var ruleContext = new PipelineArgsRuleContext<AddFromTemplateArgs>(args);

            RuleManager.RunRules(ruleContext, id);
        }

Processor with fix

    public override void Process([NotNull] AddFromTemplateArgs args)
    {
        ID id; 

        if (args.Aborted 
            || string.IsNullOrWhiteSpace(RuleFolderId) 
            || !Settings.Rules.ItemEventHandlers.RulesSupported(args.Destination.Database)
            || !ID.TryParse(RuleFolderId, out id))
        {
            return;
        }

        Assert.HasAccess(args.Destination.Access.CanCreate(), "You do not have permission to create items here.");

        using (new EventDisabler()) // fixes the exception from nexus
        {
            var item = args.Destination.Database.Engines.DataEngine.AddFromTemplate(
                args.ItemName,
                args.TemplateId,
                args.Destination,
                args.NewId);

            args.ProcessorItem = item;
            args.Result = item;
        }

        var ruleContext = new PipelineArgsRuleContext<AddFromTemplateArgs>(args);

        RuleManager.RunRules(ruleContext, id);
    }

Additional Observations

The error was only experienced about 33% of the time and only when adding an item from a branch template programmatically (never occurred when adding from the UI). The exact location of the error also appeared to change each time, and I was not able to find the source of this randomization.