Error: ValueFactory attempted to access the Value

2019-07-19 22:59发布

问题:

Error

Source File: c:\Projects\WaterfrontSeattle.org\src\Orchard\Logging\OrchardLog4netLogger.cs

Line: 63

Source Error:

Line 61: // Load the log4net thread with additional properties if they are available
Line 62: protected internal void AddExtendedThreadInfo() {
Line 63: if (_shellSettings.Value != null) {
Line 64:     ThreadContext.Properties["Tenant"] = _shellSettings.Value.Name;
Line 65: }

Research

From DuckDuckGoing, here is what we've learned, this type of error happens when we attempt to access a Lazy Value. Some Orchard Forum posts on Codeplex indicate that this means the module is out-of-date and that it needs an update to work. Some Orchard Gallery posts suggest clearing the Orchard cache as a fix. Neither of those were true for us.

Our Workaround

  1. Delete App_Data.
  2. Remove the module from all locations.
  3. Recreate Website.
  4. Restore the database.
  5. Install the module from Visual Studio's Package Manager.

Post-mortem

It seems that the most important part of the workaround was deleting App_Data. What was inside App_Data that lead to the error? We had previously tried deleting the cache.dat file without success. What else is there in App_Data that we could have deleted?

See also

  • https://orchard.codeplex.com/discussions/400331
  • https://orchard.codeplex.com/discussions/402150
  • https://orchardimagegallery.codeplex.com/workitem/24
  • http://gallery.orchardproject.net/List/Modules/Orchard.Module.Four2n.MiniProfiler

回答1:

The OP's solution is just a workaround. This problem was well explained in its GitHub issue thread:

If any tenant's shell throws on creation (in DefaultOrchardHost.CreateAndActivateShells()), the exception is supposed to be logged with OrchardLog4netLogger. However, logging methods try also to log current shell name, which is obtained through the same ShellSettings that failed to initialize, effectively forcing it to re-initialize. This leads to recursion, which ends in InvalidOperationException: ValueFactory attempted to access the Value property of this instance. due to ShellSettings lazy initialization method calling its own Lazy<>.Value. This has two effects. First, it hides the original exception, overwriting it with InvalidOperationException, which makes the underlying problem harder to debug. Second, since the exceptions thrown on Lazy<>.CreateValue() are cached and re-thrown on every invocation, this makes the tenant unusable until Orchard is restarted.

This was solved by several people, including an answer of a similar SO question: in OrchardLog4netLogger.cs replace

_shellSettings = new Lazy<ShellSettings>(LoadSettings);

with

_shellSettings = new Lazy<ShellSettings>(LoadSettings,
     System.Threading.LazyThreadSafetyMode.PublicationOnly);

In the GitHub discussion, we are currently waiting for the Orchard team to confirm this will become part of the framework core since the next version. Anyway, several other people confirmed it works.



回答2:

When troubleshooting Orchard errors, it helps to narrow down the error's location:

  1. App_Data,
  2. Source Code, and/or
  3. Database.

Delete the App_Data folder and reset/restore the Source Code and database to a time when things were working. If you can do these one at a time, that will help to isolate the error's location.

In our case, the problem was in App_Data.