fix(r2-01): filter OCE catches on the owning token in read/write wrappers + poll loop (STAB-14 defense-in-depth, task 4)
This commit is contained in:
@@ -495,7 +495,10 @@ public sealed class S7Driver
|
||||
{
|
||||
plc = await EnsureConnectedAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException) { throw; }
|
||||
// Rethrow ONLY caller cancellation. A timeout-born OCE (none expected after the
|
||||
// EnsureConnectedAsync conversion, but e.g. an S7.Net-internal CTS) must degrade the
|
||||
// batch below, not escape as teardown (STAB-14).
|
||||
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { throw; }
|
||||
catch (Exception ex)
|
||||
{
|
||||
for (var i = 0; i < fullReferences.Count; i++)
|
||||
@@ -1007,7 +1010,9 @@ public sealed class S7Driver
|
||||
{
|
||||
plc = await EnsureConnectedAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException) { throw; }
|
||||
// Rethrow ONLY caller cancellation — a timeout-born OCE degrades the batch below rather
|
||||
// than escaping as teardown (STAB-14 defense-in-depth, mirrors ReadAsync).
|
||||
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { throw; }
|
||||
catch (Exception ex)
|
||||
{
|
||||
for (var i = 0; i < writes.Count; i++)
|
||||
@@ -1401,7 +1406,10 @@ public sealed class S7Driver
|
||||
await PollOnceAsync(state, forceRaise: true, ct).ConfigureAwait(false);
|
||||
consecutiveFailures = 0;
|
||||
}
|
||||
catch (OperationCanceledException) { return; }
|
||||
// Only a teardown OCE (the loop's own token) exits the loop; any other OCE (e.g. a
|
||||
// connect-timeout that slipped past the wrapper filter) falls to the backoff path below
|
||||
// so the loop lives (STAB-14 defense-in-depth).
|
||||
catch (OperationCanceledException) when (ct.IsCancellationRequested) { return; }
|
||||
catch (Exception ex)
|
||||
{
|
||||
// First-read error — polling continues; log so the operator has an event trail.
|
||||
@@ -1415,14 +1423,17 @@ public sealed class S7Driver
|
||||
// ticks reset consecutiveFailures back to 0 so the cadence snaps back to Interval.
|
||||
var delay = ComputeBackoffDelay(state.Interval, consecutiveFailures);
|
||||
try { await Task.Delay(delay, ct).ConfigureAwait(false); }
|
||||
catch (OperationCanceledException) { return; }
|
||||
// Task.Delay can only observe ct-triggered OCE, so this filter is purely for uniformity.
|
||||
catch (OperationCanceledException) when (ct.IsCancellationRequested) { return; }
|
||||
|
||||
try
|
||||
{
|
||||
await PollOnceAsync(state, forceRaise: false, ct).ConfigureAwait(false);
|
||||
consecutiveFailures = 0;
|
||||
}
|
||||
catch (OperationCanceledException) { return; }
|
||||
// Only teardown exits; any non-teardown OCE (e.g. a slipped-through connect timeout)
|
||||
// backs off instead of killing the loop (STAB-14 defense-in-depth).
|
||||
catch (OperationCanceledException) when (ct.IsCancellationRequested) { return; }
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Sustained polling error — loop continues with backoff; log + update health.
|
||||
|
||||
Reference in New Issue
Block a user