Ticket (Solved)

Strange behavior with LayoutPart indexing

I'm not sure if this is a bug (I don't have reliable repro steps either), but I wanted to start a conversation and see if anyone else has seen this or has any ideas...

In working on my current site (using the bleeding-edge 1.9-int branch), I'm making use of a custom setup recipe. I use this to be able to completely reset my local dev environment (after database delete) to a known state with certain features enabled and some initial data (pages, navigation, widgets, etc.) Until recently (I can't remember exactly when, but within the last month or so) this has been working fine.

Now I'm seeing some strange behavior that originates in the Orchard.Layouts.Handlers.LayoutPartHandler class, IndexLayout method.

This method tries to index the HTML that results from rendering a LayoutPart shape in-memory. Part of that rendering process calls down into Orchard.Themes.CurrentThemeWorkContext to get the current theme. The error happens in this class's Get<T> method.

The issue I'm seeing is that _httpContextAccessor.Current() is null, thus an NRE is thrown. Here is the full call stack, starting from the LayoutPartHandler indexing method:

Orchard.Framework.dll!Orchard.Themes.CurrentThemeWorkContext.Get<Orchard.Environment.Extensions.Models.ExtensionDescriptor>(string name)
Orchard.Framework.dll!Orchard.Environment.WorkContextImplementation.FindResolverForState<Orchard.Environment.Extensions.Models.ExtensionDescriptor>.AnonymousMethod__2(Orchard.IWorkContextStateProvider wcsp)
System.Core.dll!System.Linq.Enumerable.WhereSelectArrayIterator<System.__Canon,System.__Canon>.MoveNext()
System.Core.dll!System.Linq.Enumerable.FirstOrDefault<System.Func<Orchard.WorkContext,Orchard.Environment.Extensions.Models.ExtensionDescriptor>>(System.Collections.Generic.IEnumerable<System.Func<Orchard.WorkContext,Orchard.Environment.Extensions.Models.ExtensionDescriptor>> source, System.Func<System.Func<Orchard.WorkContext,Orchard.Environment.Extensions.Models.ExtensionDescriptor>,bool> predicate)
Orchard.Framework.dll!Orchard.Environment.WorkContextImplementation.FindResolverForState<Orchard.Environment.Extensions.Models.ExtensionDescriptor>(string name)
mscorlib.dll!System.Collections.Concurrent.ConcurrentDictionary<string,System.Func<object>>.GetOrAdd(string key, System.Func<string,System.Func<object>> valueFactory)
Orchard.Framework.dll!Orchard.Environment.WorkContextImplementation.GetState<Orchard.Environment.Extensions.Models.ExtensionDescriptor>(string name)
Orchard.Framework.dll!Orchard.WorkContext.CurrentTheme.get()
Orchard.Layouts.dll!Orchard.Layouts.Services.ContentDisplayBase.BindPlacement.AnonymousMethod__12(string partShapeType, string differentiator, string defaultLocation)
Orchard.Framework.dll!Orchard.ContentManagement.Drivers.ContentShapeResult.ApplyImplementation(Orchard.ContentManagement.Handlers.BuildShapeContext context, string displayType)
Orchard.Framework.dll!Orchard.ContentManagement.Drivers.ContentShapeResult.Apply(Orchard.ContentManagement.Handlers.BuildDisplayContext context)
Orchard.Framework.dll!Orchard.ContentManagement.Drivers.CombinedResult.Apply(Orchard.ContentManagement.Handlers.BuildDisplayContext context)
Orchard.Layouts.dll!Orchard.Layouts.Services.ContentPartDisplay.BuildDisplay.AnonymousMethod__0(Orchard.ContentManagement.Drivers.IContentPartDriver driver)
Orchard.Framework.dll!Orchard.InvokeExtensions.Invoke<Orchard.ContentManagement.Drivers.IContentPartDriver>(System.Collections.Generic.IEnumerable<Orchard.ContentManagement.Drivers.IContentPartDriver> events, System.Action<Orchard.ContentManagement.Drivers.IContentPartDriver> dispatch, Orchard.Logging.ILogger logger)
Orchard.Layouts.dll!Orchard.Layouts.Services.ContentPartDisplay.BuildDisplay(Orchard.ContentManagement.ContentPart part, string displayType, string groupId)
Orchard.Layouts.dll!Orchard.Layouts.Handlers.LayoutPartHandler.IndexLayout(Orchard.ContentManagement.Handlers.IndexContentContext context, Orchard.Layouts.Models.LayoutPart part)

And the NRE text:

2015-04-06 17:28:52,606 [34] Orchard.Layouts.Services.ContentPartDisplay - (null) - NullReferenceException thrown from IContentPartDriver by Orchard.Layouts.Drivers.LayoutPartDriver
 (null)
System.NullReferenceException: Object reference not set to an instance of an object.
   at Orchard.Themes.CurrentThemeWorkContext.Get[T](String name) in e:\Orchard\src\Orchard\Themes\CurrentThemeWorkContext.cs:line 21
   at Orchard.Environment.WorkContextImplementation.<>c__DisplayClass7`1.<FindResolverForState>b__2(IWorkContextStateProvider wcsp) in e:\Orchard\src\Orchard\Environment\WorkContextImplementation.cs:line 32
   at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at Orchard.Environment.WorkContextImplementation.FindResolverForState[T](String name) in e:\Orchard\src\Orchard\Environment\WorkContextImplementation.cs:line 32
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Orchard.Environment.WorkContextImplementation.GetState[T](String name) in e:\Orchard\src\Orchard\Environment\WorkContextImplementation.cs:line 27
   at Orchard.WorkContext.get_CurrentTheme() in e:\Orchard\src\Orchard\WorkContext.cs:line 66
   at Orchard.Layouts.Services.ContentDisplayBase.<>c__DisplayClass13.<BindPlacement>b__12(String partShapeType, String differentiator, String defaultLocation)
   at Orchard.ContentManagement.Drivers.ContentShapeResult.ApplyImplementation(BuildShapeContext context, String displayType) in e:\Orchard\src\Orchard\ContentManagement\Drivers\ContentShapeResult.cs:line 29
   at Orchard.ContentManagement.Drivers.ContentShapeResult.Apply(BuildDisplayContext context) in e:\Orchard\src\Orchard\ContentManagement\Drivers\ContentShapeResult.cs:line 21
   at Orchard.ContentManagement.Drivers.CombinedResult.Apply(BuildDisplayContext context) in e:\Orchard\src\Orchard\ContentManagement\Drivers\CombinedResult.cs:line 28
   at Orchard.Layouts.Services.ContentPartDisplay.<>c__DisplayClass1.<BuildDisplay>b__0(IContentPartDriver driver)
   at Orchard.InvokeExtensions.Invoke[TEvents](IEnumerable`1 events, Action`1 dispatch, ILogger logger) in e:\Orchard\src\Orchard\InvokeExtensions.cs:line 17

Although the exception message cuts off, I assure you this is coming from LayoutPartHandler, and happens pretty much right after I cook the site (using my custom setup recipe) and begin interacting with it.

Of note, the current Theme is a custom theme I created, and it definitely is active at the time this exception happens. I can see all of my custom styles on the front-end, and I can see that my Theme is the active Theme in the backend.

Any thoughts?

Re: Strange behavior with LayoutPart indexing

It look like this happens in the ContentDisplayBase class of Orchard.Layouts, where the workContext.CurrentTheme is being accessed. Perhaps there is no HttpContext fake object constructed during site setup for background tasks such as the indexing background task?

When exactly does this exception occur? In a background task, or right after the site is done cooking, or as soon as you perform an HTTP request after the site is done cooking?

Tuesday, April 7, 2015 1:36:55 PM bysfmskywalker

Re: Strange behavior with LayoutPart indexing

I did some more testing. I think this issue is definitely linked to a background indexing task, here is what I found:

  1. exceptions are logged pretty much exactly 1 minute after the recipe is done cooking (e.g. on background task sweep)
  2. exceptions are logged with or without HTTP requests being made
  3. exactly 48 instances of the exception are logged, and I have exactly 48 pages with the LayoutPart attached that I am importing as part of the setup recipe (no other import data has the LayoutPart)

I'll add that my setup recipe does have commands for creating and updating a couple of indexes. But these same exception results are observed consistently, whether or not those indexing commands are run.

Tuesday, April 7, 2015 6:22:20 PM bythekaveman

Re: Strange behavior with LayoutPart indexing

You've point out a real issue. With a recent 1.9-int with only the homepage, I've just to enable "Lucene" and "Indexing" modules, create an index and update it, then I've got the same error in the log file

Then, each time I publish the homepage, an UpdateIndex() is done in the IndexingBackgroundTask, and the same error happens again

As Sipke said, it happens in ContentDisplayBase.cs, in BindPlacement() that uses the workContext CurrentTheme. This happens because in LayoutPartHandler.cs, the IndexLayout() method call _contentPartDisplay.BuildDisplay()...

In the source code I've to select an older version of the LayoutPartHandler.cs file (date: 11/14/2014) to see another implementation of IndexLayout()

Best

Saturday, April 11, 2015 3:14:24 AM byjtkech
  • jtkech
  • Lv. 13 Rookie
  • Total EXP: 1028

Re: Strange behavior with LayoutPart indexing

Yeah I think that fixed it Sipke, I can't reproduce anymore either.

Thank you!

Monday, April 13, 2015 8:07:13 PM bythekaveman

Post a reply

You need to be signed in to post a reply.

Sign In