Azure / Azure/azure-powershell

ResourceManagerCmdletBase exception handling logic destroys original exception stack trace

Open
#13,050 3 comments 0 reactions 1 assignee Claimed by @shenglol View on GitHub
act-identity-squad ARM - Core customer-reported Service Attention
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.