Skip to content

Commit 396ad9d

Browse files
committed
Implement MySqlException.IsTransient. Fixes #849
1 parent a69fea0 commit 396ad9d

File tree

3 files changed

+22
-1
lines changed

3 files changed

+22
-1
lines changed

src/MySqlConnector/MySqlException.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@ public sealed class MySqlException : DbException
4040
public override string? SqlState { get; }
4141
#endif
4242

43+
/// <summary>
44+
/// Returns <c>true</c> if this exception could indicate a transient error condition (that could succeed if retried); otherwise, <c>false</c>.
45+
/// </summary>
46+
#if NET45 || NET461 || NET471 || NETSTANDARD1_3 || NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP2_1 || NETCOREAPP3_1
47+
public bool IsTransient => IsErrorTransient(ErrorCode);
48+
#else
49+
public override bool IsTransient => IsErrorTransient(ErrorCode);
50+
#endif
51+
4352
#if !NETSTANDARD1_3
4453
private MySqlException(SerializationInfo info, StreamingContext context)
4554
: base(info, context)
@@ -115,7 +124,15 @@ internal MySqlException(MySqlErrorCode errorCode, string? sqlState, string messa
115124
internal static MySqlException CreateForTimeout() => CreateForTimeout(null);
116125

117126
internal static MySqlException CreateForTimeout(Exception? innerException) =>
118-
new MySqlException(MySqlErrorCode.CommandTimeoutExpired, "The Command Timeout expired before the operation completed.", innerException);
127+
new(MySqlErrorCode.CommandTimeoutExpired, "The Command Timeout expired before the operation completed.", innerException);
128+
129+
private static bool IsErrorTransient(MySqlErrorCode errorCode) =>
130+
errorCode is MySqlErrorCode.CommandTimeoutExpired
131+
or MySqlErrorCode.ConnectionCountError
132+
or MySqlErrorCode.LockDeadlock
133+
or MySqlErrorCode.LockWaitTimeout
134+
or MySqlErrorCode.UnableToConnectToHost
135+
or MySqlErrorCode.XARBDeadlock;
119136

120137
IDictionary? m_data;
121138
}

tests/MySqlConnector.Tests/CancellationTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ public void Test(int step, int method)
215215
var ex = Assert.Throws<MySqlException>(() => s_executeMethods[method](command));
216216
Assert.InRange(stopwatch.ElapsedMilliseconds, 2900, 3500);
217217
Assert.Equal(MySqlErrorCode.CommandTimeoutExpired, ex.ErrorCode);
218+
Assert.True(ex.IsTransient);
218219

219220
// connection is unusable
220221
Assert.Equal(ConnectionState.Closed, connection.State);

tests/SideBySide/ConnectSync.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ public void ConnectBadHost()
3030
using var connection = new MySqlConnection(csb.ConnectionString);
3131
Assert.Equal(ConnectionState.Closed, connection.State);
3232
var ex = Assert.Throws<MySqlException>(connection.Open);
33+
#if !BASELINE
34+
Assert.True(ex.IsTransient);
35+
#endif
3336
Assert.Equal((int) MySqlErrorCode.UnableToConnectToHost, ex.Number);
3437
Assert.Equal((int) MySqlErrorCode.UnableToConnectToHost, ex.Data["Server Error Code"]);
3538
Assert.Equal(ConnectionState.Closed, connection.State);

0 commit comments

Comments
 (0)