diff --git a/src/Umbraco.Core/Configuration/CoreDebug.cs b/src/Umbraco.Core/Configuration/CoreDebug.cs new file mode 100644 index 0000000000..7aa198f0e6 --- /dev/null +++ b/src/Umbraco.Core/Configuration/CoreDebug.cs @@ -0,0 +1,27 @@ +using System; + +namespace Umbraco.Core.Configuration +{ + internal static class CoreDebugExtensions + { + private static CoreDebug _coreDebug; + + public static CoreDebug CoreDebug(this UmbracoConfig config) + { + return _coreDebug ?? (_coreDebug = new CoreDebug()); + } + } + + internal class CoreDebug + { + public CoreDebug() + { + var appSettings = System.Configuration.ConfigurationManager.AppSettings; + LogUncompletedScopes = string.Equals("true", appSettings["Umbraco.CoreDebug.LogUncompletedScopes"], StringComparison.OrdinalIgnoreCase); + } + + // when true, Scope logs the stack trace for any scope that gets disposed without being completed. + // this helps troubleshooting rogue scopes that we forget to complete + public bool LogUncompletedScopes { get; private set; } + } +} diff --git a/src/Umbraco.Core/Scoping/Scope.cs b/src/Umbraco.Core/Scoping/Scope.cs index 8abbecacbe..f08b9f2e6d 100644 --- a/src/Umbraco.Core/Scoping/Scope.cs +++ b/src/Umbraco.Core/Scoping/Scope.cs @@ -1,6 +1,7 @@ using System; using System.Data; using Umbraco.Core.Cache; +using Umbraco.Core.Configuration; using Umbraco.Core.Events; using Umbraco.Core.IO; using Umbraco.Core.Persistence; @@ -341,7 +342,11 @@ namespace Umbraco.Core.Scoping { // if child did not complete we cannot complete if (completed.HasValue == false || completed.Value == false) + { + if (LogUncompletedScopes) + Logging.LogHelper.Debug("Uncompleted Child Scope at\r\n" + Environment.StackTrace); _completed = false; + } } private void EnsureNotDisposed() @@ -493,5 +498,15 @@ namespace Umbraco.Core.Scoping TryFinally(index + 1, actions); } } + + // backing field for LogUncompletedScopes + private static bool? _logUncompletedScopes; + + // caching config + // true if Umbraco.CoreDebug.LogUncompletedScope appSetting is set to "true" + private static bool LogUncompletedScopes + { + get { return (_logUncompletedScopes ?? (_logUncompletedScopes = UmbracoConfig.For.CoreDebug().LogUncompletedScopes)).Value; } + } } } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 511ad83936..1b39de70e0 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -199,6 +199,7 @@ +