fix(driver-s7-cli): resolve Medium code-review finding (Driver.S7.Cli-003)

Wrap the InitializeAsync + ReadAsync body in a try/catch so an unreachable PLC
(refused TCP connect, wrong slot) still prints the structured Host:/CPU:/Health:/
Last error: report from driver.GetHealth() instead of crashing with a stack trace.
OperationCanceledException re-throws so Ctrl+C during connect exits cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-05-22 10:17:41 -04:00
parent 086f487786
commit 26e7b8140a

View File

@@ -34,6 +34,10 @@ public sealed class ProbeCommand : S7CommandBase
var options = BuildOptions([probeTag]);
await using var driver = new S7Driver(options, DriverInstanceId);
// Driver.S7.Cli-003: wrap the entire probe sequence so that a refused/unreachable TCP
// connect still prints the structured Host/CPU/Health lines instead of crashing with a
// full .NET stack trace. InitializeAsync sets health to Faulted with the exception
// message before re-throwing, so GetHealth() always has something to report.
try
{
await driver.InitializeAsync("{}", ct);
@@ -48,6 +52,20 @@ public sealed class ProbeCommand : S7CommandBase
await console.Output.WriteLineAsync();
await console.Output.WriteLineAsync(SnapshotFormatter.Format(Address, snapshot[0]));
}
catch (OperationCanceledException)
{
throw; // Ctrl+C — let CliFx handle it normally.
}
catch
{
// Connect / read failure — print what the driver knows so far.
var health = driver.GetHealth();
await console.Output.WriteLineAsync($"Host: {Host}:{Port}");
await console.Output.WriteLineAsync($"CPU: {CpuType} rack={Rack} slot={Slot}");
await console.Output.WriteLineAsync($"Health: {health.State}");
if (health.LastError is { } err)
await console.Output.WriteLineAsync($"Last error: {err}");
}
finally
{
await driver.ShutdownAsync(CancellationToken.None);