Azure / Azure/azure-powershell
ResourceManagerCmdletBase exception handling logic destroys original exception stack trace
- Dominant language
- C#
- Stars
- 4.8k
- Forks
- 4.3k
- Avg merge
- 3d 14h
- Merged PRs (30d)
- 54
Description
## Description
The logic implemented in ResourceManagerCmdletBase.HandleException() is roughly like this:
1) if the exception is an AggregateException and contains a single inner exception, extract that inner exception;
1a) nb. current code will crash if the AggregateException contains more than one exception (!)
2) if the resulting exception is CloudException, wrap it in a ResourceManagerCloudException and throw;
3) otherwise, throw the exception object without wrapping.
The problem is in step 3), because the code uses a simple `throw sourceException;` statement, which treats the exception as a new exception, not a rethrow. As a consequence, the existing stack trace of sourceException is overwritten with a useless stack trace ending at `ResourceManagerCmdletBase.HandleException()`. This makes troubleshooting issues such as #13038 unnecessarily difficult ("where did that InvalidOperationException come from...?").
Instead of `throw`ing the exception as if it was a new one, `HandleException()` could use `ExceptionDispatchInfo` to rethrow the exception in a manner which preserves the original stack trace:
```
ExceptionDispatchInfo.Capture(sourceException).Throw();
```
## Steps to reproduce, Environment data, Module versions, Debug output, Error output
See #13038. The exception is reported like this:
```
Exception - System.InvalidCastException: Specified cast is not valid.
at
Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.ResourceManagerCmdletBase.HandleException(ExceptionDisp
atchInfo capturedException)
at Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.ResourceManagerCmdletBase.ExecuteCmdlet()
at Microsoft.WindowsAzure.Commands.Utilities.Common.AzurePSCmdlet.ProcessRecord();
```
while the actual source of the error was at `Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.CmdletBase.DeploymentCreateCmdlet.ShouldProcessGivenCurrentWhatIfFlagAndPreference()`. If the real stack trace was printed, it would have saved a considerable amount of time.
Contributor guide
Assessment
This issue has not been assessed yet.