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;
}
}