fix(driver-historian-wonderware): resolve High code-review finding (Driver.Historian.Wonderware-001)
WriteToReadOnlyFile was listed in MalformedErrors, so ClassifyOutcome/ MapOutcome routed it to PermanentFail and the store-and-forward sink dead-lettered every alarm event in the batch. But WriteToReadOnlyFile is a connection-configuration fault (the write session was opened without ReadOnly = false), not an event-payload fault — treating it as permanent silently and permanently discards alarm events on a misconfigured or regressed connection, which is data loss. Move WriteToReadOnlyFile from MalformedErrors into ConnectionErrors. The batch loop now aborts the batch, resets the connection (so the reconnect path re-opens a writable ReadOnly = false session), and defers the events as RetryPlease for the next drain tick. Updated the ClassifyOutcome theory data and added a dedicated regression test pinning WriteToReadOnlyFile -> RetryPlease. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -96,7 +96,6 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Host.Tests
|
||||
[InlineData(HistorianAccessError.ErrorValue.InvalidArgument, AlarmHistorianWriteOutcome.PermanentFail)]
|
||||
[InlineData(HistorianAccessError.ErrorValue.ValidationFailed, AlarmHistorianWriteOutcome.PermanentFail)]
|
||||
[InlineData(HistorianAccessError.ErrorValue.NullPointerArgument, AlarmHistorianWriteOutcome.PermanentFail)]
|
||||
[InlineData(HistorianAccessError.ErrorValue.WriteToReadOnlyFile, AlarmHistorianWriteOutcome.PermanentFail)]
|
||||
[InlineData(HistorianAccessError.ErrorValue.NotImplemented, AlarmHistorianWriteOutcome.PermanentFail)]
|
||||
public void ClassifyOutcome_maps_error_code_to_expected_outcome(
|
||||
HistorianAccessError.ErrorValue code, AlarmHistorianWriteOutcome expected)
|
||||
@@ -104,6 +103,20 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Host.Tests
|
||||
SdkAlarmHistorianWriteBackend.ClassifyOutcome(code).ShouldBe(expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ClassifyOutcome_WriteToReadOnlyFile_is_RetryPlease_not_PermanentFail()
|
||||
{
|
||||
// Driver.Historian.Wonderware-001 regression: WriteToReadOnlyFile is a
|
||||
// connection-configuration fault (the write session was opened without
|
||||
// ReadOnly = false), NOT a malformed-event fault. Routing it to PermanentFail
|
||||
// would dead-letter every alarm event in the batch on a misconfigured/regressed
|
||||
// connection — data loss. It must be treated as a transient connection-class
|
||||
// error so the events are deferred and retried once the connection is corrected.
|
||||
SdkAlarmHistorianWriteBackend.ClassifyOutcome(
|
||||
HistorianAccessError.ErrorValue.WriteToReadOnlyFile)
|
||||
.ShouldBe(AlarmHistorianWriteOutcome.RetryPlease);
|
||||
}
|
||||
|
||||
// ── BuildConnectionArgs — read-only vs write shaping ──────────────────
|
||||
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user