fix(abcip): libplctag ErrorBadParam at tag create is a per-tag config error, no device backoff (#570, #593)

Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
Joseph Doherty
2026-10-08 06:52:47 -04:00
parent 21267750c7
commit 6a6ac9a11f
3 changed files with 64 additions and 1 deletions
@@ -111,4 +111,41 @@ public sealed class LibplctagStatusTranslationTests
ex.Status.ShouldBe(AbStatus.Timeout);
ex.InnerException.ShouldBeSameAs(inner);
}
/// <summary>
/// #593 / #570: <c>ErrorBadParam</c> during initialisation is libplctag refusing the tag's own name — a
/// per-tag configuration error (the driver's no-backoff, no-health path), not a device connect failure.
/// </summary>
[Fact]
public async Task WrapInitialize_maps_ErrorBadParam_to_a_tag_configuration_exception()
{
var thrown = await Should.ThrowAsync<AbCipTagConfigurationException>(() =>
LibplctagStatusTranslation.WrapInitialize(() => throw new LibPlcTagException(Status.ErrorBadParam)));
thrown.InnerException.ShouldBeOfType<LibPlcTagException>();
}
/// <summary>
/// Falsification pair for the above: every OTHER initialisation failure is left alone (it still reaches
/// <c>Wrap</c> and becomes a transport status that opens the backoff window).
/// </summary>
/// <param name="status">The libplctag status.</param>
[Theory]
[InlineData(Status.ErrorTimeout)]
[InlineData(Status.ErrorBadGateway)]
[InlineData(Status.ErrorNotFound)]
public async Task WrapInitialize_leaves_other_statuses_untouched(Status status)
{
var thrown = await Should.ThrowAsync<LibPlcTagException>(() =>
LibplctagStatusTranslation.WrapInitialize(() => throw new LibPlcTagException(status)));
thrown.ShouldNotBeOfType<AbCipTagConfigurationException>();
}
/// <summary>A BadParam on the read/write path (through <c>Wrap</c>) is not reclassified as configuration.</summary>
[Fact]
public async Task Wrap_still_maps_ErrorBadParam_to_a_transport_status()
{
var thrown = await Should.ThrowAsync<AbTransportException>(() =>
LibplctagStatusTranslation.Wrap(() => throw new LibPlcTagException(Status.ErrorBadParam)));
thrown.Status.ShouldBe(AbStatus.BadConnection);
}
}