InvokeDscResourceException.cs (7491B)
1 // ----------------------------------------------------------------------------- 2 // <copyright file="InvokeDscResourceException.cs" company="Microsoft Corporation"> 3 // Copyright (c) Microsoft Corporation. Licensed under the MIT License. 4 // </copyright> 5 // ----------------------------------------------------------------------------- 6 7 namespace Microsoft.Management.Configuration.Processor.Exceptions 8 { 9 using System; 10 using System.Management.Automation; 11 using Microsoft.Management.Configuration; 12 using Microsoft.PowerShell.Commands; 13 14 /// <summary> 15 /// A call to Invoke-DscResource failed unexpectedly. 16 /// </summary> 17 internal class InvokeDscResourceException : Exception, IConfigurationUnitResultException 18 { 19 /// <summary> 20 /// The string for the Get method. 21 /// </summary> 22 public const string Get = "Get"; 23 24 /// <summary> 25 /// The string for the Set method. 26 /// </summary> 27 public const string Set = "Set"; 28 29 /// <summary> 30 /// The string for the Test method. 31 /// </summary> 32 public const string Test = "Test"; 33 34 /// <summary> 35 /// The string for the Export method. 36 /// </summary> 37 public const string Export = "Export"; 38 39 /// <summary> 40 /// Initializes a new instance of the <see cref="InvokeDscResourceException"/> class. 41 /// Use this constructor when no error is generated by the invoke and the result is not a valid value. 42 /// </summary> 43 /// <param name="method">Method.</param> 44 /// <param name="resourceName">Resource name.</param> 45 /// <param name="module">Optional module.</param> 46 public InvokeDscResourceException(string method, string resourceName, ModuleSpecification? module = null) 47 : base(CreateMessage(method, resourceName, module, null)) 48 { 49 // No message means that the invoke returned an invalid result. 50 this.HResult = ErrorCodes.WinGetConfigUnitInvokeInvalidResult; 51 this.Method = method; 52 this.ResourceName = resourceName; 53 this.Module = module; 54 } 55 56 /// <summary> 57 /// Initializes a new instance of the <see cref="InvokeDscResourceException"/> class. 58 /// Use this constructor when there is a message and the result is not valid. 59 /// </summary> 60 /// <param name="method">Method.</param> 61 /// <param name="resourceName">Resource name.</param> 62 /// <param name="message">Message.</param> 63 public InvokeDscResourceException(string method, string resourceName, string message) 64 : base(CreateMessage(method, resourceName, null, message)) 65 { 66 this.HResult = ErrorCodes.WinGetConfigUnitInvokeInvalidResult; 67 this.Method = method; 68 this.ResourceName = resourceName; 69 } 70 71 /// <summary> 72 /// Initializes a new instance of the <see cref="InvokeDscResourceException"/> class. 73 /// Use this constructor when the invoke fails with an error message. 74 /// </summary> 75 /// <param name="method">Method.</param> 76 /// <param name="resourceName">Resource name.</param> 77 /// <param name="module">Optional module.</param> 78 /// <param name="message">Message.</param> 79 /// <param name="configurationSetSource">If true, the source of this error is set to be the configuration.</param> 80 public InvokeDscResourceException(string method, string resourceName, ModuleSpecification? module, string message, bool configurationSetSource = false) 81 : base(CreateMessage(method, resourceName, module, message)) 82 { 83 this.HResult = GetHRForMethod(method); 84 this.Method = method; 85 this.ResourceName = resourceName; 86 this.Module = module; 87 this.Description = message; 88 89 if (configurationSetSource) 90 { 91 this.ResultSource = ConfigurationUnitResultSource.ConfigurationSet; 92 } 93 } 94 95 /// <summary> 96 /// Initializes a new instance of the <see cref="InvokeDscResourceException"/> class. 97 /// Use this constructor when the invoke fails with an exception. 98 /// </summary> 99 /// <param name="method">Method.</param> 100 /// <param name="resourceName">Resource name.</param> 101 /// <param name="module">Optional module.</param> 102 /// <param name="inner">The invoke exception.</param> 103 public InvokeDscResourceException(string method, string resourceName, ModuleSpecification? module, Exception inner) 104 : base(CreateMessage(method, resourceName, module, inner.Message), inner) 105 { 106 this.HResult = GetHRForMethod(method); 107 this.Method = method; 108 this.ResourceName = resourceName; 109 this.Module = module; 110 this.Description = (inner as RuntimeException)?.ErrorRecord.ToString() ?? inner.Message; 111 } 112 113 /// <summary> 114 /// Gets the invoke method. 115 /// </summary> 116 public string Method { get; } 117 118 /// <summary> 119 /// Gets the resource name. 120 /// </summary> 121 public string ResourceName { get; } 122 123 /// <summary> 124 /// Gets the module, if any. 125 /// </summary> 126 public ModuleSpecification? Module { get; } 127 128 /// <summary> 129 /// Gets a value indicating the source of the result. 130 /// </summary> 131 public ConfigurationUnitResultSource ResultSource { get; } = ConfigurationUnitResultSource.UnitProcessing; 132 133 /// <summary> 134 /// Gets the description of the result. 135 /// </summary> 136 public string Description { get; } = string.Empty; 137 138 /// <summary> 139 /// Gets the details for the result. 140 /// </summary> 141 public string Details 142 { 143 get 144 { 145 RuntimeException? re = this.InnerException as RuntimeException; 146 if (re != null) 147 { 148 return re.ErrorRecord.ScriptStackTrace; 149 } 150 151 return this.ToString(); 152 } 153 } 154 155 /// <summary> 156 /// Gets the HRESULT value for the given method. 157 /// </summary> 158 /// <param name="method">The method.</param> 159 /// <returns>The HRESULT for the method.</returns> 160 private static int GetHRForMethod(string method) 161 { 162 switch (method) 163 { 164 case Get: return ErrorCodes.WinGetConfigUnitInvokeGet; 165 case Set: return ErrorCodes.WinGetConfigUnitInvokeSet; 166 case Test: return ErrorCodes.WinGetConfigUnitInvokeTest; 167 case Export: return ErrorCodes.WinGetConfigUnitInvokeGet; 168 } 169 170 return ErrorCodes.Unexpected; 171 } 172 173 private static string CreateMessage(string method, string resourceName, ModuleSpecification? module, string? message) 174 { 175 string result = $"Failed when calling `{method}` for resource: {resourceName} [{module?.ToString() ?? "<no module>"}]"; 176 if (message != null) 177 { 178 result += $" Message: '{message}'"; 179 } 180 181 return result; 182 } 183 } 184 }