Skip to content

Commit 841a65d

Browse files
Add cloud error code and new type of error (#243)
Co-authored-by: Erich(Renyong) Wang <[email protected]>
1 parent 562a397 commit 841a65d

File tree

3 files changed

+53
-7
lines changed

3 files changed

+53
-7
lines changed

src/Authentication.Abstractions/AzurePSErrorDataKeys.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ public static class AzurePSErrorDataKeys
4141
/// </summary>
4242
public static readonly string HttpStatusCode = KeyPrefix + "HttpStatusCode";
4343

44+
/// <summary>
45+
/// Key for cloud error code in http response body
46+
/// </summary>
47+
public static readonly string CloudErrorCodeKey = KeyPrefix + "CloudErrorCode";
48+
4449
/// <summary>
4550
/// Key for authentication error code which normally comes from MSAL.NET
4651
/// </summary>
@@ -100,6 +105,7 @@ public static bool IsKeyPredefined(string key)
100105
ErrorLineNumberKey,
101106
ErrorFileNameKey,
102107
ErrorHResultKey,
108+
CloudErrorCodeKey,
103109
});
104110
}
105111
}

src/Authentication.Abstractions/Interfaces/IContainsAzPSErrorData.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,12 @@ public override string ToString()
7474
/// Error that belongs to neither UserError nor ServiceError
7575
/// </summary>
7676
public static ErrorKind InternalError = new ErrorKind("Internal");
77+
78+
/// <summary>
79+
/// Error reported by cmdlet execution but it is considered as false positive error.
80+
/// This error kind is used in the case that we don't want to introduce breaking change
81+
/// but result should be considered as succeeded.
82+
/// </summary>
83+
public static ErrorKind FalseError = new ErrorKind("FalseError");
7784
}
7885
}

src/Common/MetricHelper.cs

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -303,27 +303,25 @@ private void PopulatePropertiesFromQos(AzurePSQoSEvent qos, IDictionary<string,
303303
eventProperties.Add("interval", ((TimeSpan)(qos.StartTime - qos.PreviousEndTime)).ToString("c"));
304304
}
305305

306-
if (!qos.IsSuccess && qos.Exception?.Data?.Contains(AzurePSErrorDataKeys.ErrorKindKey) == true)
307-
{
308-
eventProperties.Add("pebcak", (qos.Exception.Data[AzurePSErrorDataKeys.ErrorKindKey] == ErrorKind.UserError).ToString());
309-
}
310-
311306
if (qos.Exception != null && populateException)
312307
{
313308
eventProperties["exception-type"] = qos.Exception.GetType().ToString();
309+
string cloudErrorCode = null;
314310
if (qos.Exception is CloudException cloudException)
315311
{
316312
eventProperties["exception-httpcode"] = cloudException.Response?.StatusCode.ToString();
313+
cloudErrorCode = cloudException.Body?.Code;
317314
}
318315
Exception innerException = qos.Exception.InnerException;
319316
List<Exception> innerExceptions = new List<Exception>();
320317
string innerExceptionStr = string.Empty;
321318
while (innerException != null)
322319
{
323320
innerExceptions.Add(innerException);
324-
if (innerException is CloudException)
321+
if (innerException is CloudException innerCloudException)
325322
{
326-
eventProperties["exception-httpcode"] = ((CloudException)qos.Exception).Response?.StatusCode.ToString();
323+
eventProperties["exception-httpcode"] = innerCloudException.Response?.StatusCode.ToString();
324+
cloudErrorCode = innerCloudException.Body?.Code;
327325
}
328326
innerException = innerException.InnerException;
329327
}
@@ -339,12 +337,33 @@ private void PopulatePropertiesFromQos(AzurePSQoSEvent qos, IDictionary<string,
339337
eventProperties["exception-stack"] = stack;
340338
}
341339

340+
if (cloudErrorCode != null && !(qos.Exception.Data?.Contains(AzurePSErrorDataKeys.CloudErrorCodeKey) == true))
341+
{
342+
qos.Exception.Data[AzurePSErrorDataKeys.CloudErrorCodeKey] = cloudErrorCode;
343+
}
344+
342345
if (qos.Exception.Data != null)
343346
{
344347
if (qos.Exception.Data.Contains(AzurePSErrorDataKeys.HttpStatusCode))
345348
{
346349
eventProperties["exception-httpcode"] = qos.Exception.Data[AzurePSErrorDataKeys.HttpStatusCode].ToString();
347350
}
351+
352+
if (qos.Exception.Data.Contains(AzurePSErrorDataKeys.CloudErrorCodeKey) == true)
353+
{
354+
string existingErrorKind = qos.Exception.Data.Contains(AzurePSErrorDataKeys.ErrorKindKey)
355+
? qos.Exception.Data[AzurePSErrorDataKeys.ErrorKindKey].ToString()
356+
: null;
357+
cloudErrorCode = (string)qos.Exception.Data[AzurePSErrorDataKeys.CloudErrorCodeKey];
358+
// For the time being, we consider ResourceNotFound and ResourceGroupNotFound as user's input error.
359+
// We are considering if ResourceNotFound should be false positive error.
360+
if (("ResourceNotFound".Equals(cloudErrorCode) || "ResourceGroupNotFound".Equals(cloudErrorCode))
361+
&& existingErrorKind != ErrorKind.FalseError)
362+
{
363+
qos.Exception.Data[AzurePSErrorDataKeys.ErrorKindKey] = ErrorKind.UserError;
364+
}
365+
}
366+
348367
StringBuilder sb = new StringBuilder();
349368
foreach (var key in qos.Exception.Data?.Keys)
350369
{
@@ -363,6 +382,20 @@ private void PopulatePropertiesFromQos(AzurePSQoSEvent qos, IDictionary<string,
363382
eventProperties["exception-data"] = sb.ToString();
364383
}
365384
}
385+
//We record the case which exception has no message
386+
if (string.IsNullOrEmpty(qos.Exception.Message))
387+
{
388+
eventProperties["exception-emptymessage"] = true.ToString();
389+
}
390+
391+
if (!qos.IsSuccess && qos.Exception?.Data?.Contains(AzurePSErrorDataKeys.ErrorKindKey) == true)
392+
{
393+
eventProperties["pebcak"] = (qos.Exception.Data[AzurePSErrorDataKeys.ErrorKindKey] == ErrorKind.UserError).ToString();
394+
if (qos.Exception.Data[AzurePSErrorDataKeys.ErrorKindKey] == ErrorKind.FalseError)
395+
{
396+
eventProperties["IsSuccess"] = true.ToString();
397+
}
398+
}
366399
}
367400

368401
if (qos.InputFromPipeline != null)

0 commit comments

Comments
 (0)