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:
@@ -22,7 +22,7 @@
|
|||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"subject": "GREEN: EnsureConnectedAsync + InitializeAsync connect-timeout OCE -> TimeoutException conversion (STAB-14 root fix)",
|
"subject": "GREEN: EnsureConnectedAsync + InitializeAsync connect-timeout OCE -> TimeoutException conversion (STAB-14 root fix)",
|
||||||
"status": "pending",
|
"status": "completed",
|
||||||
"blockedBy": [1, 2]
|
"blockedBy": [1, 2]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -187,6 +187,16 @@ public sealed class S7Driver
|
|||||||
cts.CancelAfter(_options.Timeout);
|
cts.CancelAfter(_options.Timeout);
|
||||||
await plc.OpenAsync(cts.Token).ConfigureAwait(false);
|
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
|
catch
|
||||||
{
|
{
|
||||||
// Dispose the partially-constructed connection so a failed init doesn't leak it
|
// 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);
|
cts.CancelAfter(_options.Timeout);
|
||||||
await plc.OpenAsync(cts.Token).ConfigureAwait(false);
|
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
|
catch
|
||||||
{
|
{
|
||||||
try { plc.Dispose(); } catch { /* best-effort */ }
|
try { plc.Dispose(); } catch { /* best-effort */ }
|
||||||
|
|||||||
Reference in New Issue
Block a user