< Summary

Information
Class: Elsa.Resilience.DefaultTransientExceptionStrategy
Assembly: Elsa.Resilience.Core
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Resilience.Core/Services/DefaultTransientExceptionStrategy.cs
Line coverage
100%
Covered lines: 47
Uncovered lines: 0
Coverable lines: 47
Total lines: 65
Line coverage: 100%
Branch coverage
100%
Covered branches: 4
Total branches: 4
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
IsTransient(...)100%44100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Resilience.Core/Services/DefaultTransientExceptionStrategy.cs

#LineLine coverage
 1namespace Elsa.Resilience;
 2
 3/// <summary>
 4/// Default implementation that detects common transient exceptions from the .NET framework and common patterns.
 5/// </summary>
 6public class DefaultTransientExceptionStrategy : ITransientExceptionStrategy
 7{
 28    private static readonly HashSet<string> TransientExceptionTypeNames = new(StringComparer.OrdinalIgnoreCase)
 29    {
 210        // Common framework exceptions
 211        "HttpRequestException",
 212        "TimeoutException",
 213        "TaskCanceledException",
 214        "IOException",
 215        "SocketException",
 216        "EndOfStreamException",
 217
 218        // Database-related transient exceptions (by name, not type reference)
 219        "DbException",
 220        "SqlException",
 221        "NpgsqlException",
 222        "MongoConnectionException",
 223        "MongoExecutionTimeoutException",
 224        "MongoNodeIsRecoveringException",
 225        "MongoNotPrimaryException",
 226        "MySqlException",
 227
 228        // Network-related exceptions
 229        "HttpIOException",
 230        "WebException",
 231    };
 32
 233    private static readonly HashSet<string> TransientExceptionMessagePatterns = new(StringComparer.OrdinalIgnoreCase)
 234    {
 235        "timeout",
 236        "timed out",
 237        "connection reset",
 238        "connection refused",
 239        "broken pipe",
 240        "network",
 241        "end of stream",
 242        "attempted to read past the end",
 243        "the connection is closed",
 244        "connection is not open",
 245        "failed to connect",
 246        "no connection could be made",
 247        "an existing connection was forcibly closed",
 248    };
 49
 50    /// <inheritdoc />
 51    public bool IsTransient(Exception exception)
 52    {
 53        // Check if the exception type name matches any known transient exception
 4354        var exceptionTypeName = exception.GetType().Name;
 4355        if (TransientExceptionTypeNames.Contains(exceptionTypeName))
 2156            return true;
 57
 58        // Check if the exception message contains any transient patterns
 2259        var message = exception.Message;
 60
 2261        return !string.IsNullOrEmpty(message) &&
 2262               TransientExceptionMessagePatterns
 19563                   .Any(pattern => message.Contains(pattern, StringComparison.OrdinalIgnoreCase));
 64    }
 65}