using System.Net; namespace ZB.MOM.WW.ScadaBridge.ExternalSystemGateway; /// /// WP-8: Classifies HTTP errors as transient or permanent. /// Transient: connection refused, timeout, HTTP 408/429/5xx. /// Permanent: HTTP 4xx (except 408/429). /// public static class ErrorClassifier { /// /// Determines whether an HTTP status code represents a transient failure. /// Transient: HTTP 5xx, 408 (Request Timeout) and 429 (Too Many Requests). /// Every other non-success status (the remaining 4xx) defaults to permanent — /// a permanent failure is the safe default because retrying a 4xx is unlikely to /// succeed and risks duplicate side effects. /// /// The HTTP status code to classify. /// for 5xx, 408, or 429; for all other status codes. public static bool IsTransient(HttpStatusCode statusCode) { var code = (int)statusCode; return code >= 500 || code == 408 || code == 429; } /// /// Determines whether an exception represents a transient failure. /// /// The exception to classify. /// for connection/timeout/cancellation exceptions; otherwise. public static bool IsTransient(Exception exception) { return exception is HttpRequestException or TaskCanceledException or TimeoutException or OperationCanceledException; } /// /// Creates a TransientException for S&F buffering. /// /// Human-readable failure description. /// Optional inner exception that caused the transient failure. /// A new wrapping the given details. public static TransientExternalSystemException AsTransient(string message, Exception? inner = null) { return new TransientExternalSystemException(message, inner); } } /// /// Exception type that signals a transient failure suitable for store-and-forward retry. /// public class TransientExternalSystemException : Exception { /// Initializes a new with a message and optional inner exception. /// The error message. /// Optional inner exception. public TransientExternalSystemException(string message, Exception? innerException = null) : base(message, innerException) { } } /// /// Exception type that signals a permanent failure (should not be retried). /// public class PermanentExternalSystemException : Exception { /// Gets the HTTP status code that caused the permanent failure, if applicable. public int? HttpStatusCode { get; } /// Initializes a new with a message, optional HTTP status code, and optional inner exception. /// The error message. /// The HTTP status code that triggered the failure, if available. /// Optional inner exception. public PermanentExternalSystemException(string message, int? httpStatusCode = null, Exception? innerException = null) : base(message, innerException) { HttpStatusCode = httpStatusCode; } }