From 2c2d116711e613752d556378ecd3f9b3d5ca03e7 Mon Sep 17 00:00:00 2001 From: William Baker Date: Tue, 18 Sep 2018 15:19:38 -0700 Subject: [PATCH 1/3] Catch and log exceptions thrown by ConvertDirectoryToVirtualizationRoot --- GVFS/GVFS.Common/FileSystem/IKernelDriver.cs | 3 +- GVFS/GVFS.Platform.Mac/ProjFSKext.cs | 3 +- GVFS/GVFS.Platform.Windows/ProjFSFilter.cs | 35 +++++++++++++++++--- GVFS/GVFS/CommandLine/CloneVerb.cs | 12 +++++-- GVFS/GVFS/CommandLine/DehydrateVerb.cs | 11 +++++- 5 files changed, 55 insertions(+), 9 deletions(-) diff --git a/GVFS/GVFS.Common/FileSystem/IKernelDriver.cs b/GVFS/GVFS.Common/FileSystem/IKernelDriver.cs index 270019da4..35fbdd1c1 100644 --- a/GVFS/GVFS.Common/FileSystem/IKernelDriver.cs +++ b/GVFS/GVFS.Common/FileSystem/IKernelDriver.cs @@ -1,4 +1,5 @@ using GVFS.Common.Tracing; +using System; namespace GVFS.Common.FileSystem { @@ -8,7 +9,7 @@ public interface IKernelDriver string DriverLogFolderName { get; } bool IsSupported(string normalizedEnlistmentRootPath, out string warning, out string error); string FlushDriverLogs(); - bool TryPrepareFolderForCallbacks(string folderPath, out string error); + bool TryPrepareFolderForCallbacks(string folderPath, out string error, out Exception exception); bool IsReady(JsonTracer tracer, string enlistmentRoot, out string error); } } diff --git a/GVFS/GVFS.Platform.Mac/ProjFSKext.cs b/GVFS/GVFS.Platform.Mac/ProjFSKext.cs index 9adc1d68c..ede5623fc 100644 --- a/GVFS/GVFS.Platform.Mac/ProjFSKext.cs +++ b/GVFS/GVFS.Platform.Mac/ProjFSKext.cs @@ -46,8 +46,9 @@ public bool IsReady(JsonTracer tracer, string enlistmentRoot, out string error) return true; } - public bool TryPrepareFolderForCallbacks(string folderPath, out string error) + public bool TryPrepareFolderForCallbacks(string folderPath, out string error, out Exception exception) { + exception = null; error = string.Empty; Result result = VirtualizationInstance.ConvertDirectoryToVirtualizationRoot(folderPath); if (result != Result.Success) diff --git a/GVFS/GVFS.Platform.Windows/ProjFSFilter.cs b/GVFS/GVFS.Platform.Windows/ProjFSFilter.cs index 544b5678a..7df193d96 100644 --- a/GVFS/GVFS.Platform.Windows/ProjFSFilter.cs +++ b/GVFS/GVFS.Platform.Windows/ProjFSFilter.cs @@ -30,6 +30,7 @@ public class ProjFSFilter : IKernelDriver private const string FilterLoggerSessionName = "Microsoft-Windows-ProjFS-Filter-Log"; private const string ProjFSNativeLibFileName = "ProjectedFSLib.dll"; + private const string ProjFSManagedLibFileName = "ProjectedFSLib.Managed.dll"; private const uint OkResult = 0; private const uint NameCollisionErrorResult = 0x801F0012; @@ -320,14 +321,40 @@ public string FlushDriverLogs() return sb.ToString(); } - public bool TryPrepareFolderForCallbacks(string folderPath, out string error) + public bool TryPrepareFolderForCallbacks(string folderPath, out string error, out Exception exception) { + exception = null; error = string.Empty; Guid virtualizationInstanceGuid = Guid.NewGuid(); - HResult result = VirtualizationInstance.ConvertDirectoryToVirtualizationRoot(virtualizationInstanceGuid, folderPath); - if (result != HResult.Ok) + + try + { + HResult result = VirtualizationInstance.ConvertDirectoryToVirtualizationRoot(virtualizationInstanceGuid, folderPath); + if (result != HResult.Ok) + { + error = "Failed to prepare \"" + folderPath + "\" for callbacks, error: " + result.ToString("F"); + return false; + } + } + catch (FileNotFoundException e) + { + exception = e; + + if (e.FileName.Equals(ProjFSManagedLibFileName, StringComparison.OrdinalIgnoreCase)) + { + error = $"Failed to load {ProjFSManagedLibFileName}. Ensure that ProjFS is installed and enabled"; + } + else + { + error = $"FileNotFoundException while trying to prepare \"{folderPath}\" for callbacks: {e.Message}"; + } + + return false; + } + catch (Exception e) { - error = "Failed to prepare \"" + folderPath + "\" for callbacks, error: " + result.ToString("F"); + exception = e; + error = $"Exception while trying to prepare \"{folderPath}\" for callbacks: {e.Message}"; return false; } diff --git a/GVFS/GVFS/CommandLine/CloneVerb.cs b/GVFS/GVFS/CommandLine/CloneVerb.cs index 00a429c07..5d86b909f 100644 --- a/GVFS/GVFS/CommandLine/CloneVerb.cs +++ b/GVFS/GVFS/CommandLine/CloneVerb.cs @@ -609,10 +609,18 @@ private Result CreateClone( } // Prepare the working directory folder for GVFS last to ensure that gvfs mount will fail if gvfs clone has failed + Exception exception; string prepFileSystemError; - if (!GVFSPlatform.Instance.KernelDriver.TryPrepareFolderForCallbacks(enlistment.WorkingDirectoryRoot, out prepFileSystemError)) + if (!GVFSPlatform.Instance.KernelDriver.TryPrepareFolderForCallbacks(enlistment.WorkingDirectoryRoot, out prepFileSystemError, out exception)) { - tracer.RelatedError(prepFileSystemError); + EventMetadata metadata = new EventMetadata(); + metadata.Add(nameof(prepFileSystemError), prepFileSystemError); + if (exception != null) + { + metadata.Add("Exception", exception.ToString()); + } + + tracer.RelatedError(metadata, $"{nameof(this.CreateClone)}: TryPrepareFolderForCallbacks failed"); return new Result(prepFileSystemError); } diff --git a/GVFS/GVFS/CommandLine/DehydrateVerb.cs b/GVFS/GVFS/CommandLine/DehydrateVerb.cs index 71342283a..906745f3c 100644 --- a/GVFS/GVFS/CommandLine/DehydrateVerb.cs +++ b/GVFS/GVFS/CommandLine/DehydrateVerb.cs @@ -221,9 +221,18 @@ private void Mount(ITracer tracer) private void PrepareSrcFolder(ITracer tracer, GVFSEnlistment enlistment) { + Exception exception; string error; - if (!GVFSPlatform.Instance.KernelDriver.TryPrepareFolderForCallbacks(enlistment.WorkingDirectoryRoot, out error)) + if (!GVFSPlatform.Instance.KernelDriver.TryPrepareFolderForCallbacks(enlistment.WorkingDirectoryRoot, out error, out exception)) { + EventMetadata metadata = new EventMetadata(); + metadata.Add(nameof(error), error); + if (exception != null) + { + metadata.Add("Exception", exception.ToString()); + } + + tracer.RelatedError(metadata, $"{nameof(this.PrepareSrcFolder)}: TryPrepareFolderForCallbacks failed"); this.ReportErrorAndExit(tracer, "Failed to recreate the virtualization root: " + error); } } From f2bda4254a57e3218a0dc1c74da6f8543a76a96e Mon Sep 17 00:00:00 2001 From: William Baker Date: Tue, 18 Sep 2018 15:53:38 -0700 Subject: [PATCH 2/3] Catch exceptions one level higher --- GVFS/GVFS.Common/FileSystem/IKernelDriver.cs | 3 +- GVFS/GVFS.Platform.Mac/ProjFSKext.cs | 3 +- GVFS/GVFS.Platform.Windows/ProjFSFilter.cs | 35 +++----------------- GVFS/GVFS/CommandLine/CloneVerb.cs | 27 +++++++++------ GVFS/GVFS/CommandLine/DehydrateVerb.cs | 22 +++++++----- 5 files changed, 36 insertions(+), 54 deletions(-) diff --git a/GVFS/GVFS.Common/FileSystem/IKernelDriver.cs b/GVFS/GVFS.Common/FileSystem/IKernelDriver.cs index 35fbdd1c1..270019da4 100644 --- a/GVFS/GVFS.Common/FileSystem/IKernelDriver.cs +++ b/GVFS/GVFS.Common/FileSystem/IKernelDriver.cs @@ -1,5 +1,4 @@ using GVFS.Common.Tracing; -using System; namespace GVFS.Common.FileSystem { @@ -9,7 +8,7 @@ public interface IKernelDriver string DriverLogFolderName { get; } bool IsSupported(string normalizedEnlistmentRootPath, out string warning, out string error); string FlushDriverLogs(); - bool TryPrepareFolderForCallbacks(string folderPath, out string error, out Exception exception); + bool TryPrepareFolderForCallbacks(string folderPath, out string error); bool IsReady(JsonTracer tracer, string enlistmentRoot, out string error); } } diff --git a/GVFS/GVFS.Platform.Mac/ProjFSKext.cs b/GVFS/GVFS.Platform.Mac/ProjFSKext.cs index ede5623fc..9adc1d68c 100644 --- a/GVFS/GVFS.Platform.Mac/ProjFSKext.cs +++ b/GVFS/GVFS.Platform.Mac/ProjFSKext.cs @@ -46,9 +46,8 @@ public bool IsReady(JsonTracer tracer, string enlistmentRoot, out string error) return true; } - public bool TryPrepareFolderForCallbacks(string folderPath, out string error, out Exception exception) + public bool TryPrepareFolderForCallbacks(string folderPath, out string error) { - exception = null; error = string.Empty; Result result = VirtualizationInstance.ConvertDirectoryToVirtualizationRoot(folderPath); if (result != Result.Success) diff --git a/GVFS/GVFS.Platform.Windows/ProjFSFilter.cs b/GVFS/GVFS.Platform.Windows/ProjFSFilter.cs index 7df193d96..544b5678a 100644 --- a/GVFS/GVFS.Platform.Windows/ProjFSFilter.cs +++ b/GVFS/GVFS.Platform.Windows/ProjFSFilter.cs @@ -30,7 +30,6 @@ public class ProjFSFilter : IKernelDriver private const string FilterLoggerSessionName = "Microsoft-Windows-ProjFS-Filter-Log"; private const string ProjFSNativeLibFileName = "ProjectedFSLib.dll"; - private const string ProjFSManagedLibFileName = "ProjectedFSLib.Managed.dll"; private const uint OkResult = 0; private const uint NameCollisionErrorResult = 0x801F0012; @@ -321,40 +320,14 @@ public string FlushDriverLogs() return sb.ToString(); } - public bool TryPrepareFolderForCallbacks(string folderPath, out string error, out Exception exception) + public bool TryPrepareFolderForCallbacks(string folderPath, out string error) { - exception = null; error = string.Empty; Guid virtualizationInstanceGuid = Guid.NewGuid(); - - try - { - HResult result = VirtualizationInstance.ConvertDirectoryToVirtualizationRoot(virtualizationInstanceGuid, folderPath); - if (result != HResult.Ok) - { - error = "Failed to prepare \"" + folderPath + "\" for callbacks, error: " + result.ToString("F"); - return false; - } - } - catch (FileNotFoundException e) - { - exception = e; - - if (e.FileName.Equals(ProjFSManagedLibFileName, StringComparison.OrdinalIgnoreCase)) - { - error = $"Failed to load {ProjFSManagedLibFileName}. Ensure that ProjFS is installed and enabled"; - } - else - { - error = $"FileNotFoundException while trying to prepare \"{folderPath}\" for callbacks: {e.Message}"; - } - - return false; - } - catch (Exception e) + HResult result = VirtualizationInstance.ConvertDirectoryToVirtualizationRoot(virtualizationInstanceGuid, folderPath); + if (result != HResult.Ok) { - exception = e; - error = $"Exception while trying to prepare \"{folderPath}\" for callbacks: {e.Message}"; + error = "Failed to prepare \"" + folderPath + "\" for callbacks, error: " + result.ToString("F"); return false; } diff --git a/GVFS/GVFS/CommandLine/CloneVerb.cs b/GVFS/GVFS/CommandLine/CloneVerb.cs index 5d86b909f..6cf233ba2 100644 --- a/GVFS/GVFS/CommandLine/CloneVerb.cs +++ b/GVFS/GVFS/CommandLine/CloneVerb.cs @@ -609,22 +609,29 @@ private Result CreateClone( } // Prepare the working directory folder for GVFS last to ensure that gvfs mount will fail if gvfs clone has failed - Exception exception; - string prepFileSystemError; - if (!GVFSPlatform.Instance.KernelDriver.TryPrepareFolderForCallbacks(enlistment.WorkingDirectoryRoot, out prepFileSystemError, out exception)) + Result prepForCallbacksResult = new Result(true); + try { - EventMetadata metadata = new EventMetadata(); - metadata.Add(nameof(prepFileSystemError), prepFileSystemError); - if (exception != null) + string prepFileSystemError; + if (!GVFSPlatform.Instance.KernelDriver.TryPrepareFolderForCallbacks(enlistment.WorkingDirectoryRoot, out prepFileSystemError)) { - metadata.Add("Exception", exception.ToString()); + prepForCallbacksResult = new Result(prepFileSystemError); } - + } + catch (Exception e) + { + EventMetadata metadata = new EventMetadata(); + metadata.Add("Exception", e.ToString()); tracer.RelatedError(metadata, $"{nameof(this.CreateClone)}: TryPrepareFolderForCallbacks failed"); - return new Result(prepFileSystemError); + prepForCallbacksResult = new Result($"Failed to prepare \"{enlistment.WorkingDirectoryRoot}\" for callbacks, exception: {e.Message}"); } - return new Result(true); + if (!prepForCallbacksResult.Success) + { + tracer.RelatedError($"TryPrepareFolderForCallbacks failed, error: {prepForCallbacksResult.ErrorMessage}"); + } + + return prepForCallbacksResult; } private void CreateGitScript(GVFSEnlistment enlistment) diff --git a/GVFS/GVFS/CommandLine/DehydrateVerb.cs b/GVFS/GVFS/CommandLine/DehydrateVerb.cs index 906745f3c..a82e7cd13 100644 --- a/GVFS/GVFS/CommandLine/DehydrateVerb.cs +++ b/GVFS/GVFS/CommandLine/DehydrateVerb.cs @@ -221,19 +221,23 @@ private void Mount(ITracer tracer) private void PrepareSrcFolder(ITracer tracer, GVFSEnlistment enlistment) { - Exception exception; - string error; - if (!GVFSPlatform.Instance.KernelDriver.TryPrepareFolderForCallbacks(enlistment.WorkingDirectoryRoot, out error, out exception)) + try { - EventMetadata metadata = new EventMetadata(); - metadata.Add(nameof(error), error); - if (exception != null) + string error; + if (!GVFSPlatform.Instance.KernelDriver.TryPrepareFolderForCallbacks(enlistment.WorkingDirectoryRoot, out error)) { - metadata.Add("Exception", exception.ToString()); + EventMetadata metadata = new EventMetadata(); + metadata.Add(nameof(error), error); + tracer.RelatedError(metadata, $"{nameof(this.PrepareSrcFolder)}: TryPrepareFolderForCallbacks failed"); + this.ReportErrorAndExit(tracer, "Failed to recreate the virtualization root: " + error); } - + } + catch (Exception e) + { + EventMetadata metadata = new EventMetadata(); + metadata.Add("Exception", e.ToString()); tracer.RelatedError(metadata, $"{nameof(this.PrepareSrcFolder)}: TryPrepareFolderForCallbacks failed"); - this.ReportErrorAndExit(tracer, "Failed to recreate the virtualization root: " + error); + this.ReportErrorAndExit(tracer, "Failed to recreate the virtualization root: " + e.Message); } } From d67eac1a4d0f7e280d5a7d348434fd93de8a4693 Mon Sep 17 00:00:00 2001 From: William Baker Date: Fri, 21 Sep 2018 16:52:24 -0700 Subject: [PATCH 3/3] PR Feedback: Move exception handling into TryPrepareFolderForCallbacks --- GVFS/GVFS.Common/FileSystem/IKernelDriver.cs | 3 +- GVFS/GVFS.Platform.Mac/ProjFSKext.cs | 3 +- GVFS/GVFS.Platform.Windows/ProjFSFilter.cs | 51 ++++++++++++++++---- GVFS/GVFS/CommandLine/CloneVerb.cs | 27 ++++------- GVFS/GVFS/CommandLine/DehydrateVerb.cs | 22 ++++----- 5 files changed, 65 insertions(+), 41 deletions(-) diff --git a/GVFS/GVFS.Common/FileSystem/IKernelDriver.cs b/GVFS/GVFS.Common/FileSystem/IKernelDriver.cs index 270019da4..35fbdd1c1 100644 --- a/GVFS/GVFS.Common/FileSystem/IKernelDriver.cs +++ b/GVFS/GVFS.Common/FileSystem/IKernelDriver.cs @@ -1,4 +1,5 @@ using GVFS.Common.Tracing; +using System; namespace GVFS.Common.FileSystem { @@ -8,7 +9,7 @@ public interface IKernelDriver string DriverLogFolderName { get; } bool IsSupported(string normalizedEnlistmentRootPath, out string warning, out string error); string FlushDriverLogs(); - bool TryPrepareFolderForCallbacks(string folderPath, out string error); + bool TryPrepareFolderForCallbacks(string folderPath, out string error, out Exception exception); bool IsReady(JsonTracer tracer, string enlistmentRoot, out string error); } } diff --git a/GVFS/GVFS.Platform.Mac/ProjFSKext.cs b/GVFS/GVFS.Platform.Mac/ProjFSKext.cs index 9adc1d68c..ede5623fc 100644 --- a/GVFS/GVFS.Platform.Mac/ProjFSKext.cs +++ b/GVFS/GVFS.Platform.Mac/ProjFSKext.cs @@ -46,8 +46,9 @@ public bool IsReady(JsonTracer tracer, string enlistmentRoot, out string error) return true; } - public bool TryPrepareFolderForCallbacks(string folderPath, out string error) + public bool TryPrepareFolderForCallbacks(string folderPath, out string error, out Exception exception) { + exception = null; error = string.Empty; Result result = VirtualizationInstance.ConvertDirectoryToVirtualizationRoot(folderPath); if (result != Result.Success) diff --git a/GVFS/GVFS.Platform.Windows/ProjFSFilter.cs b/GVFS/GVFS.Platform.Windows/ProjFSFilter.cs index 544b5678a..3d7b4ce92 100644 --- a/GVFS/GVFS.Platform.Windows/ProjFSFilter.cs +++ b/GVFS/GVFS.Platform.Windows/ProjFSFilter.cs @@ -30,6 +30,7 @@ public class ProjFSFilter : IKernelDriver private const string FilterLoggerSessionName = "Microsoft-Windows-ProjFS-Filter-Log"; private const string ProjFSNativeLibFileName = "ProjectedFSLib.dll"; + private const string ProjFSManagedLibFileName = "ProjectedFSLib.Managed.dll"; private const uint OkResult = 0; private const uint NameCollisionErrorResult = 0x801F0012; @@ -320,18 +321,34 @@ public string FlushDriverLogs() return sb.ToString(); } - public bool TryPrepareFolderForCallbacks(string folderPath, out string error) + public bool TryPrepareFolderForCallbacks(string folderPath, out string error, out Exception exception) { - error = string.Empty; - Guid virtualizationInstanceGuid = Guid.NewGuid(); - HResult result = VirtualizationInstance.ConvertDirectoryToVirtualizationRoot(virtualizationInstanceGuid, folderPath); - if (result != HResult.Ok) + exception = null; + try { - error = "Failed to prepare \"" + folderPath + "\" for callbacks, error: " + result.ToString("F"); - return false; + return this.TryPrepareFolderForCallbacksImpl(folderPath, out error); } + catch (FileNotFoundException e) + { + exception = e; - return true; + if (e.FileName.Equals(ProjFSManagedLibFileName, StringComparison.OrdinalIgnoreCase)) + { + error = $"Failed to load {ProjFSManagedLibFileName}. Ensure that ProjFS is installed and enabled"; + } + else + { + error = $"FileNotFoundException while trying to prepare \"{folderPath}\" for callbacks: {e.Message}"; + } + + return false; + } + catch (Exception e) + { + exception = e; + error = $"Exception while trying to prepare \"{folderPath}\" for callbacks: {e.Message}"; + return false; + } } // TODO 1050199: Once the service is an optional component, GVFS should only attempt to attach @@ -562,7 +579,23 @@ private static EventMetadata CreateEventMetadata(Exception e = null) private static ProcessResult CallPowershellCommand(string command) { return ProcessHelper.Run("powershell.exe", "-NonInteractive -NoProfile -Command \"& { " + command + " }\""); - } + } + + // Using an Impl method allows TryPrepareFolderForCallbacks to catch any ProjFS dependency related exceptions + // thrown in the process of calling this method. + private bool TryPrepareFolderForCallbacksImpl(string folderPath, out string error) + { + error = string.Empty; + Guid virtualizationInstanceGuid = Guid.NewGuid(); + HResult result = VirtualizationInstance.ConvertDirectoryToVirtualizationRoot(virtualizationInstanceGuid, folderPath); + if (result != HResult.Ok) + { + error = "Failed to prepare \"" + folderPath + "\" for callbacks, error: " + result.ToString("F"); + return false; + } + + return true; + } private static class NativeMethods { diff --git a/GVFS/GVFS/CommandLine/CloneVerb.cs b/GVFS/GVFS/CommandLine/CloneVerb.cs index 6cf233ba2..5d86b909f 100644 --- a/GVFS/GVFS/CommandLine/CloneVerb.cs +++ b/GVFS/GVFS/CommandLine/CloneVerb.cs @@ -609,29 +609,22 @@ private Result CreateClone( } // Prepare the working directory folder for GVFS last to ensure that gvfs mount will fail if gvfs clone has failed - Result prepForCallbacksResult = new Result(true); - try + Exception exception; + string prepFileSystemError; + if (!GVFSPlatform.Instance.KernelDriver.TryPrepareFolderForCallbacks(enlistment.WorkingDirectoryRoot, out prepFileSystemError, out exception)) { - string prepFileSystemError; - if (!GVFSPlatform.Instance.KernelDriver.TryPrepareFolderForCallbacks(enlistment.WorkingDirectoryRoot, out prepFileSystemError)) + EventMetadata metadata = new EventMetadata(); + metadata.Add(nameof(prepFileSystemError), prepFileSystemError); + if (exception != null) { - prepForCallbacksResult = new Result(prepFileSystemError); + metadata.Add("Exception", exception.ToString()); } - } - catch (Exception e) - { - EventMetadata metadata = new EventMetadata(); - metadata.Add("Exception", e.ToString()); - tracer.RelatedError(metadata, $"{nameof(this.CreateClone)}: TryPrepareFolderForCallbacks failed"); - prepForCallbacksResult = new Result($"Failed to prepare \"{enlistment.WorkingDirectoryRoot}\" for callbacks, exception: {e.Message}"); - } - if (!prepForCallbacksResult.Success) - { - tracer.RelatedError($"TryPrepareFolderForCallbacks failed, error: {prepForCallbacksResult.ErrorMessage}"); + tracer.RelatedError(metadata, $"{nameof(this.CreateClone)}: TryPrepareFolderForCallbacks failed"); + return new Result(prepFileSystemError); } - return prepForCallbacksResult; + return new Result(true); } private void CreateGitScript(GVFSEnlistment enlistment) diff --git a/GVFS/GVFS/CommandLine/DehydrateVerb.cs b/GVFS/GVFS/CommandLine/DehydrateVerb.cs index a82e7cd13..906745f3c 100644 --- a/GVFS/GVFS/CommandLine/DehydrateVerb.cs +++ b/GVFS/GVFS/CommandLine/DehydrateVerb.cs @@ -221,23 +221,19 @@ private void Mount(ITracer tracer) private void PrepareSrcFolder(ITracer tracer, GVFSEnlistment enlistment) { - try + Exception exception; + string error; + if (!GVFSPlatform.Instance.KernelDriver.TryPrepareFolderForCallbacks(enlistment.WorkingDirectoryRoot, out error, out exception)) { - string error; - if (!GVFSPlatform.Instance.KernelDriver.TryPrepareFolderForCallbacks(enlistment.WorkingDirectoryRoot, out error)) + EventMetadata metadata = new EventMetadata(); + metadata.Add(nameof(error), error); + if (exception != null) { - EventMetadata metadata = new EventMetadata(); - metadata.Add(nameof(error), error); - tracer.RelatedError(metadata, $"{nameof(this.PrepareSrcFolder)}: TryPrepareFolderForCallbacks failed"); - this.ReportErrorAndExit(tracer, "Failed to recreate the virtualization root: " + error); + metadata.Add("Exception", exception.ToString()); } - } - catch (Exception e) - { - EventMetadata metadata = new EventMetadata(); - metadata.Add("Exception", e.ToString()); + tracer.RelatedError(metadata, $"{nameof(this.PrepareSrcFolder)}: TryPrepareFolderForCallbacks failed"); - this.ReportErrorAndExit(tracer, "Failed to recreate the virtualization root: " + e.Message); + this.ReportErrorAndExit(tracer, "Failed to recreate the virtualization root: " + error); } }