Skip to content

Commit 01da7a5

Browse files
authored
Fix CTRL-C error. (#8359)
1 parent bc37e0c commit 01da7a5

File tree

1 file changed

+47
-30
lines changed

1 file changed

+47
-30
lines changed

src/Aspire.Cli/Program.cs

Lines changed: 47 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
using Microsoft.Extensions.Logging;
1515
using Spectre.Console;
1616
using Spectre.Console.Rendering;
17+
using StreamJsonRpc;
1718

1819
namespace Aspire.Cli;
1920

@@ -218,44 +219,60 @@ await AnsiConsole.Live(table).StartAsync(async context => {
218219

219220
var resourceStates = backchannel.GetResourceStatesAsync(ct);
220221

221-
await foreach(var resourceState in resourceStates)
222+
try
222223
{
223-
knownResources[resourceState.Resource] = resourceState;
224+
await foreach(var resourceState in resourceStates)
225+
{
226+
knownResources[resourceState.Resource] = resourceState;
224227

225-
table.Rows.Clear();
228+
table.Rows.Clear();
226229

227-
foreach (var knownResource in knownResources)
228-
{
229-
var nameRenderable = new Text(knownResource.Key, new Style().Foreground(Color.White));
230-
231-
var typeRenderable = new Text(knownResource.Value.Type, new Style().Foreground(Color.White));
232-
233-
var stateRenderable = knownResource.Value.State switch {
234-
"Running" => new Text(knownResource.Value.State, new Style().Foreground(Color.Green)),
235-
"Starting" => new Text(knownResource.Value.State, new Style().Foreground(Color.LightGreen)),
236-
"FailedToStart" => new Text(knownResource.Value.State, new Style().Foreground(Color.Red)),
237-
"Waiting" => new Text(knownResource.Value.State, new Style().Foreground(Color.White)),
238-
"Unhealthy" => new Text(knownResource.Value.State, new Style().Foreground(Color.Yellow)),
239-
"Exited" => new Text(knownResource.Value.State, new Style().Foreground(Color.Grey)),
240-
"Finished" => new Text(knownResource.Value.State, new Style().Foreground(Color.Grey)),
241-
"NotStarted" => new Text(knownResource.Value.State, new Style().Foreground(Color.Grey)),
242-
_ => new Text(knownResource.Value.State ?? "Unknown", new Style().Foreground(Color.Grey))
243-
};
244-
245-
IRenderable endpointsRenderable = new Text("None");
246-
if (knownResource.Value.Endpoints?.Length > 0)
230+
foreach (var knownResource in knownResources)
247231
{
248-
endpointsRenderable = new Rows(
249-
knownResource.Value.Endpoints.Select(e => new Text(e, new Style().Link(e)))
250-
);
232+
var nameRenderable = new Text(knownResource.Key, new Style().Foreground(Color.White));
233+
234+
var typeRenderable = new Text(knownResource.Value.Type, new Style().Foreground(Color.White));
235+
236+
var stateRenderable = knownResource.Value.State switch {
237+
"Running" => new Text(knownResource.Value.State, new Style().Foreground(Color.Green)),
238+
"Starting" => new Text(knownResource.Value.State, new Style().Foreground(Color.LightGreen)),
239+
"FailedToStart" => new Text(knownResource.Value.State, new Style().Foreground(Color.Red)),
240+
"Waiting" => new Text(knownResource.Value.State, new Style().Foreground(Color.White)),
241+
"Unhealthy" => new Text(knownResource.Value.State, new Style().Foreground(Color.Yellow)),
242+
"Exited" => new Text(knownResource.Value.State, new Style().Foreground(Color.Grey)),
243+
"Finished" => new Text(knownResource.Value.State, new Style().Foreground(Color.Grey)),
244+
"NotStarted" => new Text(knownResource.Value.State, new Style().Foreground(Color.Grey)),
245+
_ => new Text(knownResource.Value.State ?? "Unknown", new Style().Foreground(Color.Grey))
246+
};
247+
248+
IRenderable endpointsRenderable = new Text("None");
249+
if (knownResource.Value.Endpoints?.Length > 0)
250+
{
251+
endpointsRenderable = new Rows(
252+
knownResource.Value.Endpoints.Select(e => new Text(e, new Style().Link(e)))
253+
);
254+
}
255+
256+
table.AddRow(nameRenderable, typeRenderable, stateRenderable, endpointsRenderable);
251257
}
252258

253-
table.AddRow(nameRenderable, typeRenderable, stateRenderable, endpointsRenderable);
259+
context.Refresh();
254260
}
255-
256-
context.Refresh();
257261
}
258-
262+
catch (ConnectionLostException ex) when (ex.InnerException is OperationCanceledException)
263+
{
264+
// This exception will be thrown if the cancellation request reaches the WaitForExitAsync
265+
// call on the process and shuts down the apphost before the JsonRpc connection gets it meaning
266+
// that the apphost side of the RPC connection will be closed. Therefore if we get a
267+
// ConnectionLostException AND the inner exception is an OperationCancelledException we can
268+
// asume that the apphost was shutdown and we can ignore it.
269+
}
270+
catch (OperationCanceledException)
271+
{
272+
// This exception will be thrown if the cancellation request reaches the our side
273+
// of the backchannel side first and the connection is torn down on our-side
274+
// gracefully. We can ignore this exception as well.
275+
}
259276
});
260277

261278
return await pendingRun;

0 commit comments

Comments
 (0)