From e03c12b63978b269e012591f22ba19e6628041f8 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 6 Jul 2026 21:17:27 +0000 Subject: [PATCH] refactor: extract shared transience computation into TransienceCalculator Both PrimaryPortInnerErrors and SecondaryPortInnerErrors carried a byte-for-byte identical ComputeTransience implementation. Extract that logic into an internal TransienceCalculator helper and have both classes delegate to it, so the transience resolution rules live in a single authoritative place. Behaviour is unchanged; existing coverage in PortInnerErrorsTests exercises all branches through the public API. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_011eKgk4tXrcECvpepJwGshF --- FirstClassErrors/PrimaryPortInnerErrors.cs | 15 +---- FirstClassErrors/SecondaryPortInnerErrors.cs | 15 +---- FirstClassErrors/TransienceCalculator.cs | 59 ++++++++++++++++++++ 3 files changed, 61 insertions(+), 28 deletions(-) create mode 100644 FirstClassErrors/TransienceCalculator.cs diff --git a/FirstClassErrors/PrimaryPortInnerErrors.cs b/FirstClassErrors/PrimaryPortInnerErrors.cs index 70efb70..7451181 100644 --- a/FirstClassErrors/PrimaryPortInnerErrors.cs +++ b/FirstClassErrors/PrimaryPortInnerErrors.cs @@ -89,20 +89,7 @@ public PrimaryPortInnerErrors Add(PrimaryPortError error) { /// It determines the transience based on the property. /// public Transience ComputeTransience() { - IEnumerable infraErrors = _errors.OfType(); - - bool hasTransient = false; - - foreach (InfrastructureError? error in infraErrors) { - switch (error.Transience) { - case Transience.NonTransient: return Transience.NonTransient; - case Transience.Transient: hasTransient = true; break; - } - } - - return hasTransient - ? Transience.Transient - : Transience.Unknown; + return TransienceCalculator.Compute(_errors); } internal IReadOnlyList ToList() { diff --git a/FirstClassErrors/SecondaryPortInnerErrors.cs b/FirstClassErrors/SecondaryPortInnerErrors.cs index 5f40087..37e5885 100644 --- a/FirstClassErrors/SecondaryPortInnerErrors.cs +++ b/FirstClassErrors/SecondaryPortInnerErrors.cs @@ -106,20 +106,7 @@ internal IReadOnlyList ToList() { /// property of each error. /// public Transience ComputeTransience() { - IEnumerable infraErrors = _errors.OfType(); - - bool hasTransient = false; - - foreach (InfrastructureError? error in infraErrors) { - switch (error.Transience) { - case Transience.NonTransient: return Transience.NonTransient; - case Transience.Transient: hasTransient = true; break; - } - } - - return hasTransient - ? Transience.Transient - : Transience.Unknown; + return TransienceCalculator.Compute(_errors); } /// diff --git a/FirstClassErrors/TransienceCalculator.cs b/FirstClassErrors/TransienceCalculator.cs new file mode 100644 index 0000000..f2204d4 --- /dev/null +++ b/FirstClassErrors/TransienceCalculator.cs @@ -0,0 +1,59 @@ +namespace FirstClassErrors; + +/// +/// Computes the overall of a collection of errors. +/// +/// +/// This helper centralizes the transience resolution rules so that the various inner-error collections +/// (for instance and ) share a +/// single, authoritative implementation rather than duplicating the logic. +/// +internal static class TransienceCalculator { + + #region Statics members declarations + + /// + /// Computes the overall transience of the specified errors. + /// + /// The errors to evaluate. + /// + /// A value indicating the overall transience of the errors: + /// + /// + /// if any error is explicitly non-transient. + /// + /// + /// + /// if at least one error is transient and none are + /// non-transient. + /// + /// + /// + /// if no errors are classified as transient or non-transient. + /// + /// + /// + /// + /// Only errors of type are taken into account; the transience is determined + /// based on their property. + /// + public static Transience Compute(IEnumerable errors) { + IEnumerable infraErrors = errors.OfType(); + + bool hasTransient = false; + + foreach (InfrastructureError error in infraErrors) { + switch (error.Transience) { + case Transience.NonTransient: return Transience.NonTransient; + case Transience.Transient: hasTransient = true; break; + } + } + + return hasTransient + ? Transience.Transient + : Transience.Unknown; + } + + #endregion + +}