Skip to content

Commit 865a71b

Browse files
authored
Swallow all the exceptions from the callback (#18301)
1 parent d7f4f8b commit 865a71b

File tree

7 files changed

+283
-146
lines changed

7 files changed

+283
-146
lines changed

tools/Az.Tools.Predictor/Az.Tools.Predictor.Test/Mocks/MockAzPredictorTelemetryClient.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public record TelemetryRecord(string EventName, IDictionary<string, string> Prop
2929
public SuggestionDisplayedTelemetryData SuggestionDisplayedData { get; internal set; }
3030
public SuggestionAcceptedTelemetryData SuggestionAcceptedData { get; internal set; }
3131
public ParameterMapTelemetryData ParameterMapData { get; internal set; }
32+
public GeneralExceptionTelemetryData ExceptionData { get; internal set; }
3233
public IList<TelemetryRecord> RecordedTelemetry { get; internal set; } = new List<TelemetryRecord>();
3334
public IList<ITelemetryData> DispatchedTelemetry { get; internal set; } = new List<ITelemetryData>();
3435
public AggregatedTelemetryData RecordedAggregatedData { get; private set; }
@@ -101,6 +102,13 @@ public override void OnLoadParameterMap(ParameterMapTelemetryData telemetryData)
101102
ParameterMapData = telemetryData;
102103
}
103104

105+
/// <inheritdoc/>
106+
public override void OnGeneralException(GeneralExceptionTelemetryData telemetryData)
107+
{
108+
base.OnGeneralException(telemetryData);
109+
ExceptionData = telemetryData;
110+
}
111+
104112
public void FlushTelemetry() => SendAggregatedTelemetryData();
105113

106114
public void ResetWaitingTasks()

tools/Az.Tools.Predictor/Az.Tools.Predictor/AzPredictor.cs

Lines changed: 145 additions & 141 deletions
Large diffs are not rendered by default.

tools/Az.Tools.Predictor/Az.Tools.Predictor/AzPredictorService.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -314,12 +314,13 @@ public virtual CommandLineSuggestion GetSuggestion(PredictionContext context, in
314314
}
315315

316316
/// <inheritdoc/>
317-
public virtual void RecordHistory(CommandAst history)
318-
{
319-
Validation.CheckArgument(history, $"{nameof(history)} cannot be null.");
317+
public virtual void RecordHistory(CommandAst history) =>
318+
ExceptionUtilities.RecordExceptionWrapper(_telemetryClient, () =>
319+
{
320+
Validation.CheckArgument(history, $"{nameof(history)} cannot be null.");
320321

321-
_parameterValuePredictor.ProcessHistoryCommand(history);
322-
}
322+
_parameterValuePredictor.ProcessHistoryCommand(history);
323+
});
323324

324325
/// <inheritdoc/>
325326
public bool IsSupportedCommand(string cmd) => IsRecognizedCommand(cmd)

tools/Az.Tools.Predictor/Az.Tools.Predictor/Telemetry/AzPredictorTelemetryClient.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ public virtual void OnGetSuggestion(GetSuggestionTelemetryData telemetryData)
139139
System.Diagnostics.Trace.WriteLine("Recording GetSuggestion");
140140
#endif
141141
}
142+
142143
/// <inheritdoc/>
143144
public virtual void OnSuggestionDisplayed(SuggestionDisplayedTelemetryData telemetryData)
144145
{
@@ -179,6 +180,16 @@ public void OnParseCommandLineFailure(CommandLineParsingTelemetryData telemetryD
179180
#endif
180181
}
181182

183+
/// <inheritdoc/>
184+
public virtual void OnGeneralException(GeneralExceptionTelemetryData telemetryData)
185+
{
186+
PostTelemetryData(telemetryData);
187+
188+
#if TELEMETRY_TRACE && DEBUG
189+
System.Diagnostics.Trace.WriteLine("Recording GeneralException");
190+
#endif
191+
}
192+
182193
/// <summary>
183194
/// Gets the client that can send telemetry via Application Insight.
184195
/// </summary>
@@ -216,6 +227,9 @@ protected virtual void DispatchTelemetryData(ITelemetryData telemetryData)
216227
case CommandLineParsingTelemetryData commandLineParsing:
217228
ProcessTelemetryData(commandLineParsing);
218229
break;
230+
case GeneralExceptionTelemetryData exception:
231+
ProcessTelemetryData(exception);
232+
break;
219233
}
220234
}
221235

@@ -553,6 +567,17 @@ private void ProcessTelemetryData(CommandLineParsingTelemetryData telemetryData)
553567
}
554568
}
555569

570+
/// <summary>
571+
/// Processes the telemetry with the exception.
572+
/// </summary>
573+
private void ProcessTelemetryData(GeneralExceptionTelemetryData telemetryData)
574+
{
575+
if (telemetryData.Exception != null)
576+
{
577+
SendException("An error occurred that wasn't caught in any scenarios.", telemetryData, telemetryData.Exception);
578+
}
579+
}
580+
556581
/// <summary>
557582
/// Add the common properties to the telemetry event.
558583
/// </summary>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System;
16+
using System.Management.Automation.Subsystem.Prediction;
17+
18+
namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Telemetry
19+
{
20+
/// <summary>
21+
/// The data to collect in <see cref="ITelemetryClient.OnGeneralException(GeneralExceptionTelemetryData)"/>.
22+
/// </summary>
23+
public sealed class GeneralExceptionTelemetryData : ITelemetryData
24+
{
25+
/// <inheritdoc/>
26+
public PredictionClient Client { get; }
27+
28+
/// <inheritdoc/>
29+
string ITelemetryData.CommandId { get; set; }
30+
31+
/// <inheritdoc/>
32+
string ITelemetryData.RequestId { get; set; }
33+
34+
/// <summary>
35+
/// Gets the exception.
36+
/// </summary>
37+
public Exception Exception { get; }
38+
39+
/// <summary>
40+
/// Creates a new instance of <see cref="GeneralExceptionTelemetryData"/>.
41+
/// </summary>
42+
/// <param name="exception">The exception that is thrown.</param>
43+
public GeneralExceptionTelemetryData(Exception exception)
44+
{
45+
Exception = exception;
46+
}
47+
}
48+
}

tools/Az.Tools.Predictor/Az.Tools.Predictor/Telemetry/ITelemetryClient.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// limitations under the License.
1313
// ----------------------------------------------------------------------------------
1414

15+
using System;
16+
1517
namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Telemetry
1618
{
1719
/// <summary>
@@ -70,5 +72,14 @@ public interface ITelemetryClient
7072
/// </summary>
7173
/// <param name="telemetryData">The data to collect.</param>
7274
public void OnParseCommandLineFailure(CommandLineParsingTelemetryData telemetryData);
75+
76+
/// <summary>
77+
/// Collects when there is a non-specific failure in the code.
78+
/// </summary>
79+
/// <remarks>
80+
/// Use the other methods to record the exceptions in those events.
81+
/// This is only used when it's not in any specific telemetry event.
82+
/// </remarks>
83+
public void OnGeneralException(GeneralExceptionTelemetryData e);
7384
}
7485
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System;
16+
using Microsoft.Azure.PowerShell.Tools.AzPredictor.Telemetry;
17+
18+
namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Utilities
19+
{
20+
/// <summary>
21+
/// A utilities class to provide functions around exceptions.
22+
/// </summary>
23+
internal static class ExceptionUtilities
24+
{
25+
/// <summary>
26+
/// Handles all exceptions and record it in the telemetry.
27+
/// </summary>
28+
public static void RecordExceptionWrapper(ITelemetryClient telemetryClient, Action action)
29+
{
30+
try
31+
{
32+
action();
33+
}
34+
catch (Exception e)
35+
{
36+
telemetryClient.OnGeneralException(new GeneralExceptionTelemetryData(e));
37+
}
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)