Commit 9611b76f authored by Marc Gravell's avatar Marc Gravell

Merge branch 'innerexception' of...

Merge branch 'innerexception' of https://github.com/deepakverma/StackExchange.Redis into deepakverma-innerexception

# Conflicts:
#	StackExchange.Redis/StackExchange/Redis/ExceptionFactory.cs
#	StackExchange.Redis/StackExchange/Redis/ServerEndPoint.cs
parents 96aca8ee eee8bd04
......@@ -87,6 +87,23 @@ public void SocketFailureError()
}
}
#if DEBUG // needs AllowConnect, which is DEBUG only
[Test]
public void AbortOnConnectFailFalseConnectTimeoutError()
{
string name, password;
GetAzureCredentials(out name, out password);
var options = new ConfigurationOptions();
options.EndPoints.Add(name + ".redis.cache.windows.net");
options.Ssl = true;
options.ConnectTimeout = 0;
options.Password = password;
using (var muxer = ConnectionMultiplexer.Connect(options))
{
var ex = Assert.Throws<RedisConnectionException>(() => muxer.GetDatabase().Ping());
Assert.That(ex.Message, Does.Contain("ConnectTimeout"));
}
}
[Test]
public void CheckFailureRecovered()
{
......
......@@ -876,7 +876,11 @@ private static ConnectionMultiplexer ConnectImpl(Func<ConnectionMultiplexer> mul
task.ObserveErrors();
if (muxer.RawConfig.AbortOnConnectFail)
{
throw ExceptionFactory.UnableToConnect("Timeout");
throw ExceptionFactory.UnableToConnect("ConnectTimeout");
}
else
{
muxer.LastException = ExceptionFactory.UnableToConnect("ConnectTimeout");
}
}
if (!task.Result) throw ExceptionFactory.UnableToConnect(muxer.failureMessage);
......@@ -992,6 +996,9 @@ private void OnHeartbeat()
return unchecked(Environment.TickCount - VolatileWrapper.Read(ref lastHeartbeatTicks)) / 1000;
}
}
internal Exception LastException { get; set; }
internal static long LastGlobalHeartbeatSecondsAgo => unchecked(Environment.TickCount - VolatileWrapper.Read(ref lastGlobalHeartbeatTicks)) / 1000;
internal CompletionManager UnprocessableCompletionManager => unprocessableCompletionManager;
......@@ -1137,6 +1144,10 @@ public bool Configure(TextWriter log = null)
{
throw new TimeoutException();
}
else
{
LastException = new TimeoutException("ConnectTimeout");
}
return false;
}
return task.Result;
......
......@@ -75,9 +75,25 @@ internal static Exception MultiSlot(bool includeDetail, Message message)
return ex;
}
internal static string GetInnerMostExceptionMessage(Exception e)
{
if (e == null)
{
return "";
}
else
{
while (e.InnerException != null)
{
e = e.InnerException;
}
return e.Message;
}
}
internal static Exception NoConnectionAvailable(bool includeDetail, RedisCommand command, Message message, ServerEndPoint server, ServerEndPoint[] serverSnapshot)
{
string s = GetLabel(includeDetail, command, message);
string commandLabel = GetLabel(includeDetail, command, message);
if (server != null)
{
......@@ -85,27 +101,42 @@ internal static Exception NoConnectionAvailable(bool includeDetail, RedisCommand
//otherwise it would output state of all the endpoints
serverSnapshot = new ServerEndPoint[] { server };
}
string exceptionmessage = "No connection is available to service this operation: " + s ;
var innerException = PopulateInnerExceptions(serverSnapshot);
StringBuilder exceptionmessage = new StringBuilder("No connection is available to service this operation: ").Append(commandLabel);
string innermostExceptionstring = GetInnerMostExceptionMessage(innerException);
if (!string.IsNullOrEmpty(innermostExceptionstring))
{
exceptionmessage.Append("; ").Append(innermostExceptionstring);
}
#if !CORE_CLR
if (includeDetail)
{
exceptionmessage += ". " + ConnectionMultiplexer.GetThreadPoolAndCPUSummary();
exceptionmessage.Append("; ").Append(ConnectionMultiplexer.GetThreadPoolAndCPUSummary());
}
#endif
var ex = new RedisConnectionException(ConnectionFailureType.UnableToResolvePhysicalConnection, exceptionmessage, GetServerSnapshotInnerExceptions(serverSnapshot));
var ex = new RedisConnectionException(ConnectionFailureType.UnableToResolvePhysicalConnection, exceptionmessage.ToString(), innerException);
if (includeDetail)
{
AddDetail(ex, message, server, s);
AddDetail(ex, message, server, commandLabel);
}
return ex;
}
internal static Exception GetServerSnapshotInnerExceptions(ServerEndPoint[] serverSnapshot)
internal static Exception PopulateInnerExceptions(ServerEndPoint[] serverSnapshot)
{
List<Exception> innerExceptions = new List<Exception>();
if (serverSnapshot != null)
{
if (serverSnapshot.Length > 0 && serverSnapshot[0].Multiplexer.LastException != null)
{
innerExceptions.Add(serverSnapshot[0].Multiplexer.LastException);
}
for (int i = 0; i < serverSnapshot.Length; i++)
{
if (serverSnapshot[i].LastException != null)
......
......@@ -101,8 +101,7 @@ internal Exception LastException
//check if subscription endpoint has a better lastexception
if (tmp2 != null && tmp2.LastException != null)
{
var failureType = tmp2.LastException.Data["Redis-FailureType"];
if (failureType != null && !failureType.ToString().Equals(ConnectionFailureType.UnableToConnect.ToString()))
if (tmp2.LastException.Data.Contains("Redis-FailureType") && !tmp2.LastException.Data["Redis-FailureType"].ToString().Equals(ConnectionFailureType.UnableToConnect.ToString()))
{
return tmp2.LastException;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment