fix(r2-01): surface connect-timeout as TimeoutException, not OCE — poll loops no longer die on unreachable-host outages (STAB-14, task 3)
This commit is contained in:
@@ -187,6 +187,16 @@ public sealed class S7Driver
|
||||
cts.CancelAfter(_options.Timeout);
|
||||
await plc.OpenAsync(cts.Token).ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
// The linked CancelAfter fired — a connect TIMEOUT, not a caller cancellation.
|
||||
// Surface it as a TimeoutException so init-time and reconnect-time timeouts report
|
||||
// the same exception type (STAB-14 consistency); the outer catch still faults health.
|
||||
try { plc.Dispose(); } catch { }
|
||||
throw new TimeoutException(
|
||||
$"S7 connect to {_options.Host}:{_options.Port} timed out after " +
|
||||
$"{(int)_options.Timeout.TotalMilliseconds} ms.");
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Dispose the partially-constructed connection so a failed init doesn't leak it
|
||||
@@ -1205,6 +1215,17 @@ public sealed class S7Driver
|
||||
cts.CancelAfter(_options.Timeout);
|
||||
await plc.OpenAsync(cts.Token).ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException) when (!ct.IsCancellationRequested)
|
||||
{
|
||||
// The linked CancelAfter fired — a connect TIMEOUT, not a caller cancellation.
|
||||
// Surface it as a connection FAILURE (TimeoutException) so callers route it through
|
||||
// their degrade paths: an escaping OCE reads as teardown and permanently killed the
|
||||
// subscription poll loops (STAB-14, the unreachable-host regression in the Crit-3 fix).
|
||||
try { plc.Dispose(); } catch { /* best-effort */ }
|
||||
throw new TimeoutException(
|
||||
$"S7 connect to {_options.Host}:{_options.Port} timed out after " +
|
||||
$"{(int)_options.Timeout.TotalMilliseconds} ms.");
|
||||
}
|
||||
catch
|
||||
{
|
||||
try { plc.Dispose(); } catch { /* best-effort */ }
|
||||
|
||||
Reference in New Issue
Block a user