Commit 87cb5f21 authored by Marc Gravell's avatar Marc Gravell

Better detail (optional) in faults

parent 5ec10092
...@@ -56,7 +56,7 @@ internal void AppendDeltas(StringBuilder sb) ...@@ -56,7 +56,7 @@ internal void AppendDeltas(StringBuilder sb)
internal void AssertAvailable(RedisCommand command) internal void AssertAvailable(RedisCommand command)
{ {
if (map[(int)command] == null) throw ExceptionFactory.CommandDisabled(command); if (map[(int)command] == null) throw ExceptionFactory.CommandDisabled(false, command, null, null);
} }
internal byte[] GetBytes(RedisCommand command) internal byte[] GetBytes(RedisCommand command)
......
...@@ -270,11 +270,11 @@ public void ExportConfiguration(Stream destination, ExportOptions options = Expo ...@@ -270,11 +270,11 @@ public void ExportConfiguration(Stream destination, ExportOptions options = Expo
internal void MakeMaster(ServerEndPoint server, ReplicationChangeOptions options, TextWriter log) internal void MakeMaster(ServerEndPoint server, ReplicationChangeOptions options, TextWriter log)
{ {
CommandMap.AssertAvailable(RedisCommand.SLAVEOF); CommandMap.AssertAvailable(RedisCommand.SLAVEOF);
if (!configuration.AllowAdmin) throw ExceptionFactory.AdminModeNotEnabled(RedisCommand.SLAVEOF); if (!configuration.AllowAdmin) throw ExceptionFactory.AdminModeNotEnabled(IncludeDetailInExceptions, RedisCommand.SLAVEOF, null, server);
if (server == null) throw new ArgumentNullException("server"); if (server == null) throw new ArgumentNullException("server");
var srv = new RedisServer(this, server, null); var srv = new RedisServer(this, server, null);
if (!srv.IsConnected) throw ExceptionFactory.NoConnectionAvailable(RedisCommand.SLAVEOF); if (!srv.IsConnected) throw ExceptionFactory.NoConnectionAvailable(IncludeDetailInExceptions, RedisCommand.SLAVEOF, null, server);
if (log == null) log = TextWriter.Null; if (log == null) log = TextWriter.Null;
CommandMap.AssertAvailable(RedisCommand.SLAVEOF); CommandMap.AssertAvailable(RedisCommand.SLAVEOF);
...@@ -396,7 +396,7 @@ internal void LogLocked(TextWriter log, string line, params object[] args) ...@@ -396,7 +396,7 @@ internal void LogLocked(TextWriter log, string line, params object[] args)
internal void CheckMessage(Message message) internal void CheckMessage(Message message)
{ {
if (!configuration.AllowAdmin && message.IsAdmin) if (!configuration.AllowAdmin && message.IsAdmin)
throw ExceptionFactory.AdminModeNotEnabled(message.Command); throw ExceptionFactory.AdminModeNotEnabled(IncludeDetailInExceptions, message.Command, message, null);
CommandMap.AssertAvailable(message.Command); CommandMap.AssertAvailable(message.Command);
} }
...@@ -790,7 +790,7 @@ internal ServerEndPoint GetServerEndPoint(EndPoint endpoint) ...@@ -790,7 +790,7 @@ internal ServerEndPoint GetServerEndPoint(EndPoint endpoint)
private ConnectionMultiplexer(ConfigurationOptions configuration) private ConnectionMultiplexer(ConfigurationOptions configuration)
{ {
if (configuration == null) throw new ArgumentNullException("configuration"); if (configuration == null) throw new ArgumentNullException("configuration");
ShowKeysInTimeout = true; IncludeDetailInExceptions = true;
this.configuration = configuration; this.configuration = configuration;
this.CommandMap = configuration.CommandMap; this.CommandMap = configuration.CommandMap;
...@@ -1434,14 +1434,14 @@ private bool TryPushMessageToBridge<T>(Message message, ResultProcessor<T> proce ...@@ -1434,14 +1434,14 @@ private bool TryPushMessageToBridge<T>(Message message, ResultProcessor<T> proce
if (message.IsMasterOnly() && server.IsSlave) if (message.IsMasterOnly() && server.IsSlave)
{ {
throw ExceptionFactory.MasterOnly(message.Command); throw ExceptionFactory.MasterOnly(IncludeDetailInExceptions, message.Command, message, server);
} }
if (server.ServerType == ServerType.Cluster) if (server.ServerType == ServerType.Cluster)
{ {
if (message.GetHashSlot(ServerSelectionStrategy) == ServerSelectionStrategy.MultipleSlots) if (message.GetHashSlot(ServerSelectionStrategy) == ServerSelectionStrategy.MultipleSlots)
{ {
throw ExceptionFactory.MultiSlot(); throw ExceptionFactory.MultiSlot(IncludeDetailInExceptions, message);
} }
} }
if (!server.IsConnected) if (!server.IsConnected)
...@@ -1455,7 +1455,8 @@ private bool TryPushMessageToBridge<T>(Message message, ResultProcessor<T> proce ...@@ -1455,7 +1455,8 @@ private bool TryPushMessageToBridge<T>(Message message, ResultProcessor<T> proce
if (message.Db >= 0) if (message.Db >= 0)
{ {
int availableDatabases = server.Databases; int availableDatabases = server.Databases;
if (availableDatabases > 0 && message.Db >= availableDatabases) throw ExceptionFactory.DatabaseOutfRange(message.Db); if (availableDatabases > 0 && message.Db >= availableDatabases) throw ExceptionFactory.DatabaseOutfRange(
IncludeDetailInExceptions, message.Db, message, server);
} }
Trace("Queueing on server: " + message); Trace("Queueing on server: " + message);
...@@ -1603,7 +1604,7 @@ internal Task<T> ExecuteAsyncImpl<T>(Message message, ResultProcessor<T> process ...@@ -1603,7 +1604,7 @@ internal Task<T> ExecuteAsyncImpl<T>(Message message, ResultProcessor<T> process
var source = ResultBox<T>.Get(tcs); var source = ResultBox<T>.Get(tcs);
if (!TryPushMessageToBridge(message, processor, source, ref server)) if (!TryPushMessageToBridge(message, processor, source, ref server))
{ {
ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(message.Command)); ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(IncludeDetailInExceptions, message.Command, message, server));
} }
return tcs.Task; return tcs.Task;
} }
...@@ -1644,7 +1645,7 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser ...@@ -1644,7 +1645,7 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser
{ {
if (!TryPushMessageToBridge(message, processor, source, ref server)) if (!TryPushMessageToBridge(message, processor, source, ref server))
{ {
throw ExceptionFactory.NoConnectionAvailable(message.Command); throw ExceptionFactory.NoConnectionAvailable(IncludeDetailInExceptions, message.Command, message, server);
} }
if (Monitor.Wait(source, timeoutMilliseconds)) if (Monitor.Wait(source, timeoutMilliseconds))
...@@ -1656,15 +1657,15 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser ...@@ -1656,15 +1657,15 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser
Trace("Timeout performing " + message.ToString()); Trace("Timeout performing " + message.ToString());
Interlocked.Increment(ref syncTimeouts); Interlocked.Increment(ref syncTimeouts);
string errMessage; string errMessage;
if (server == null) if (server == null || !IncludeDetailInExceptions)
{ {
errMessage = "Timeout performing " + (ShowKeysInTimeout ? message.CommandAndKey : message.Command.ToString()); errMessage = "Timeout performing " + message.Command.ToString();
} }
else else
{ {
int inst, qu, qs, qc, wr, wq; int inst, qu, qs, qc, wr, wq;
int queue = server.GetOutstandingCount(message.Command, out inst, out qu, out qs, out qc, out wr, out wq); int queue = server.GetOutstandingCount(message.Command, out inst, out qu, out qs, out qc, out wr, out wq);
var sb = new StringBuilder("Timeout performing ").Append(ShowKeysInTimeout ? message.CommandAndKey : message.Command.ToString()) var sb = new StringBuilder("Timeout performing ").Append(message.CommandAndKey)
.Append(", inst: ").Append(inst) .Append(", inst: ").Append(inst)
.Append(", queue: ").Append(queue).Append(", qu=").Append(qu) .Append(", queue: ").Append(queue).Append(", qu=").Append(qu)
.Append(", qs=").Append(qs).Append(", qc=").Append(qc) .Append(", qs=").Append(qs).Append(", qc=").Append(qc)
...@@ -1677,7 +1678,8 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser ...@@ -1677,7 +1678,8 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser
else Interlocked.Exchange(ref stormLogSnapshot, log); else Interlocked.Exchange(ref stormLogSnapshot, log);
} }
} }
throw new TimeoutException(errMessage); // very important not to return "source" to the pool here throw ExceptionFactory.Timeout(IncludeDetailInExceptions, errMessage, message, server);
// very important not to return "source" to the pool here
} }
} }
// snapshot these so that we can recycle the box // snapshot these so that we can recycle the box
...@@ -1691,9 +1693,9 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser ...@@ -1691,9 +1693,9 @@ internal T ExecuteSyncImpl<T>(Message message, ResultProcessor<T> processor, Ser
} }
/// <summary> /// <summary>
/// Should the key name be displayed when generating a timeout message? /// Should exceptions include identifiable details? (key names, additional .Data annotations)
/// </summary> /// </summary>
public bool ShowKeysInTimeout { get; set; } public bool IncludeDetailInExceptions { get; set; }
int haveStormLog = 0, stormLogThreshold = 15; int haveStormLog = 0, stormLogThreshold = 15;
string stormLogSnapshot; string stormLogSnapshot;
......
...@@ -218,7 +218,7 @@ internal void SimulateConnectionFailure() ...@@ -218,7 +218,7 @@ internal void SimulateConnectionFailure()
{ {
if (!multiplexer.RawConfig.AllowAdmin) if (!multiplexer.RawConfig.AllowAdmin)
{ {
throw ExceptionFactory.AdminModeNotEnabled(RedisCommand.DEBUG); // close enough throw ExceptionFactory.AdminModeNotEnabled(multiplexer.IncludeDetailInExceptions, RedisCommand.DEBUG, null, serverEndPoint); // close enough
} }
var tmp = physical; var tmp = physical;
if (tmp != null) tmp.RecordConnectionFailed(ConnectionFailureType.SocketFailure); if (tmp != null) tmp.RecordConnectionFailed(ConnectionFailureType.SocketFailure);
......
...@@ -4,41 +4,95 @@ namespace StackExchange.Redis ...@@ -4,41 +4,95 @@ namespace StackExchange.Redis
{ {
internal static class ExceptionFactory internal static class ExceptionFactory
{ {
internal static Exception AdminModeNotEnabled(RedisCommand command) internal static Exception AdminModeNotEnabled(bool includeDetail, RedisCommand command, Message message, ServerEndPoint server)
{ {
return new RedisCommandException("This operation is not available unless admin mode is enabled: " + command.ToString()); string s = GetLabel(includeDetail, command, message);
var ex = new RedisCommandException("This operation is not available unless admin mode is enabled: " + s);
if (includeDetail) AddDetail(ex, message, server, s);
return ex;
} }
internal static Exception NoConnectionAvailable(RedisCommand command) static string GetLabel(bool includeDetail, RedisCommand command, Message message)
{ {
return new RedisConnectionException(ConnectionFailureType.UnableToResolvePhysicalConnection, "No connection is available to service this operation: " + command.ToString()); return message == null ? command.ToString() : (includeDetail ? message.CommandAndKey : message.Command.ToString());
} }
internal static Exception CommandDisabled(RedisCommand command) internal static Exception NoConnectionAvailable(bool includeDetail, RedisCommand command, Message message, ServerEndPoint server)
{ {
return new RedisCommandException("This operation has been disabled in the command-map and cannot be used: " + command.ToString()); string s = GetLabel(includeDetail, command, message);
var ex = new RedisConnectionException(ConnectionFailureType.UnableToResolvePhysicalConnection, "No connection is available to service this operation: " + s);
if (includeDetail) AddDetail(ex, message, server, s);
return ex;
} }
internal static Exception MultiSlot()
const string DataCommandKey = "redis-command",
DataServerKey = "redis-server";
private static void AddDetail(Exception exception, Message message, ServerEndPoint server, string label)
{
if (exception != null)
{
if (message != null) exception.Data.Add(DataCommandKey, message.CommandAndKey);
else if(label != null) exception.Data.Add(DataCommandKey, label);
if (server != null) exception.Data.Add(DataServerKey, Format.ToString(server.EndPoint));
}
}
internal static Exception CommandDisabled(bool includeDetail, RedisCommand command, Message message, ServerEndPoint server)
{
string s = GetLabel(includeDetail, command, message);
var ex = new RedisCommandException("This operation has been disabled in the command-map and cannot be used: " + s);
if (includeDetail) AddDetail(ex, message, server, s);
return ex;
}
internal static Exception MultiSlot(bool includeDetail, Message message)
{
var ex = new RedisCommandException("Multi-key operations must involve a single slot; keys can use 'hash tags' to help this, i.e. '{/users/12345}/account' and '{/users/12345}/contacts' will always be in the same slot");
if (includeDetail) AddDetail(ex, message, null, null);
return ex;
}
internal static Exception DatabaseOutfRange(bool includeDetail, int targetDatabase, Message message, ServerEndPoint server)
{
var ex = new RedisCommandException("The database does not exist on the server: " + targetDatabase);
if (includeDetail) AddDetail(ex, message, server, null);
return ex;
}
internal static Exception DatabaseRequired(bool includeDetail, RedisCommand command)
{ {
return new RedisCommandException("Multi-key operations must involve a single slot; keys can use 'hash tags' to help this, i.e. '{/users/12345}/account' and '{/users/12345}/contacts' will always be in the same slot"); string s = command.ToString();
var ex = new RedisCommandException("A target database is required for " + s);
if (includeDetail) AddDetail(ex, null, null, s);
return ex;
} }
internal static Exception DatabaseOutfRange(int targetDatabase) internal static Exception DatabaseNotRequired(bool includeDetail, RedisCommand command)
{ {
return new RedisCommandException("The database does not exist on the server: " + targetDatabase); string s = command.ToString();
var ex = new RedisCommandException("A target database is not required for " + s);
if (includeDetail) AddDetail(ex, null, null, s);
return ex;
} }
internal static Exception DatabaseRequired(RedisCommand command) internal static Exception MasterOnly(bool includeDetail, RedisCommand command, Message message, ServerEndPoint server)
{ {
return new RedisCommandException("A target database is required for " + command.ToString()); string s = GetLabel(includeDetail, command, message);
var ex = new RedisCommandException("Command cannot be issued to a slave: " + s);
if (includeDetail) AddDetail(ex, message, server, s);
return ex;
} }
internal static Exception DatabaseNotRequired(RedisCommand command) internal static Exception Timeout(bool includeDetail, string errorMessage, Message message, ServerEndPoint server)
{ {
return new RedisCommandException("A target database is not required for " + command.ToString()); var ex = new TimeoutException(errorMessage);
if (includeDetail) AddDetail(ex, message, server, null);
return ex;
} }
internal static Exception MasterOnly(RedisCommand command) internal static Exception ConnectionFailure(bool includeDetail, ConnectionFailureType failureType, string message, ServerEndPoint server)
{ {
return new RedisCommandException(command + " cannot be issued to a slave"); var ex = new RedisConnectionException(failureType, message);
if (includeDetail) AddDetail(ex, null, server, null);
return ex;
} }
} }
} }
...@@ -93,14 +93,14 @@ protected Message(int db, CommandFlags flags, RedisCommand command) ...@@ -93,14 +93,14 @@ protected Message(int db, CommandFlags flags, RedisCommand command)
{ {
if (dbNeeded) if (dbNeeded)
{ {
throw ExceptionFactory.DatabaseRequired(command); throw ExceptionFactory.DatabaseRequired(false, command);
} }
} }
else else
{ {
if (!dbNeeded) if (!dbNeeded)
{ {
throw ExceptionFactory.DatabaseNotRequired(command); throw ExceptionFactory.DatabaseNotRequired(false, command);
} }
} }
...@@ -109,7 +109,7 @@ protected Message(int db, CommandFlags flags, RedisCommand command) ...@@ -109,7 +109,7 @@ protected Message(int db, CommandFlags flags, RedisCommand command)
switch (GetMasterSlaveFlags(flags)) switch (GetMasterSlaveFlags(flags))
{ {
case CommandFlags.DemandSlave: case CommandFlags.DemandSlave:
throw ExceptionFactory.MasterOnly(command); throw ExceptionFactory.MasterOnly(false, command, null, null);
case CommandFlags.DemandMaster: case CommandFlags.DemandMaster:
// already fine as-is // already fine as-is
break; break;
......
...@@ -257,7 +257,7 @@ internal void KeepAlive() ...@@ -257,7 +257,7 @@ internal void KeepAlive()
multiplexer.Trace("Enqueue: " + msg); multiplexer.Trace("Enqueue: " + msg);
if(!TryEnqueue(msg, serverEndPoint.IsSlave)) if(!TryEnqueue(msg, serverEndPoint.IsSlave))
{ {
OnInternalError(ExceptionFactory.NoConnectionAvailable(msg.Command)); OnInternalError(ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, msg.Command, msg, serverEndPoint));
} }
} }
} }
...@@ -605,7 +605,7 @@ private void SelectDatabase(PhysicalConnection connection, Message message) ...@@ -605,7 +605,7 @@ private void SelectDatabase(PhysicalConnection connection, Message message)
int db = message.Db; int db = message.Db;
if (db >= 0) if (db >= 0)
{ {
var sel = connection.GetSelectDatabaseCommand(db); var sel = connection.GetSelectDatabaseCommand(db, message);
if (sel != null) if (sel != null)
{ {
connection.Enqueue(sel); connection.Enqueue(sel);
...@@ -624,7 +624,7 @@ private bool WriteMessageToServer(PhysicalConnection connection, Message message ...@@ -624,7 +624,7 @@ private bool WriteMessageToServer(PhysicalConnection connection, Message message
bool isMasterOnly = message.IsMasterOnly(); bool isMasterOnly = message.IsMasterOnly();
if (isMasterOnly && serverEndPoint.IsSlave) if (isMasterOnly && serverEndPoint.IsSlave)
{ {
throw ExceptionFactory.MasterOnly(message.Command); throw ExceptionFactory.MasterOnly(multiplexer.IncludeDetailInExceptions, message.Command, message, ServerEndPoint);
} }
SelectDatabase(connection, message); SelectDatabase(connection, message);
......
...@@ -286,7 +286,7 @@ internal Message GetReadModeCommand(bool isMasterOnly) ...@@ -286,7 +286,7 @@ internal Message GetReadModeCommand(bool isMasterOnly)
return null; return null;
} }
internal Message GetSelectDatabaseCommand(int targetDatabase) internal Message GetSelectDatabaseCommand(int targetDatabase, Message message)
{ {
if (targetDatabase < 0) return null; if (targetDatabase < 0) return null;
if (targetDatabase != currentDatabase) if (targetDatabase != currentDatabase)
...@@ -297,19 +297,19 @@ internal Message GetSelectDatabaseCommand(int targetDatabase) ...@@ -297,19 +297,19 @@ internal Message GetSelectDatabaseCommand(int targetDatabase)
if (!serverEndpoint.HasDatabases) // only db0 is available on cluster if (!serverEndpoint.HasDatabases) // only db0 is available on cluster
{ {
if (targetDatabase != 0) if (targetDatabase != 0)
{ // should never see this, since the API doesn't allow it { // should never see this, since the API doesn't allow it; thus not too worried about ExceptionFactory
throw new RedisCommandException("Multiple databases are not supported on this server; cannot switch to database: " + targetDatabase); throw new RedisCommandException("Multiple databases are not supported on this server; cannot switch to database: " + targetDatabase);
} }
return null; return null;
} }
if (TransactionActive) if (TransactionActive)
{// should never see this, since the API doesn't allow it {// should never see this, since the API doesn't allow it; thus not too worried about ExceptionFactory
throw new RedisCommandException("Multiple databases inside a transaction are not currently supported" + targetDatabase); throw new RedisCommandException("Multiple databases inside a transaction are not currently supported" + targetDatabase);
} }
if (available != 0 && targetDatabase >= available) // we positively know it is out of range if (available != 0 && targetDatabase >= available) // we positively know it is out of range
{ {
throw ExceptionFactory.DatabaseOutfRange(targetDatabase); throw ExceptionFactory.DatabaseOutfRange(multiplexer.IncludeDetailInExceptions, targetDatabase, message, serverEndpoint);
} }
bridge.Trace("Switching database: " + targetDatabase); bridge.Trace("Switching database: " + targetDatabase);
currentDatabase = targetDatabase; currentDatabase = targetDatabase;
...@@ -351,7 +351,7 @@ internal void WriteHeader(RedisCommand command, int arguments) ...@@ -351,7 +351,7 @@ internal void WriteHeader(RedisCommand command, int arguments)
var commandBytes = multiplexer.CommandMap.GetBytes(command); var commandBytes = multiplexer.CommandMap.GetBytes(command);
if (commandBytes == null) if (commandBytes == null)
{ {
throw ExceptionFactory.CommandDisabled(command); throw ExceptionFactory.CommandDisabled(multiplexer.IncludeDetailInExceptions, command, null, bridge.ServerEndPoint);
} }
outStream.WriteByte((byte)'*'); outStream.WriteByte((byte)'*');
WriteRaw(outStream, arguments + 1); WriteRaw(outStream, arguments + 1);
...@@ -742,7 +742,7 @@ private RawResult ReadArray(byte[] buffer, ref int offset, ref int count) ...@@ -742,7 +742,7 @@ private RawResult ReadArray(byte[] buffer, ref int offset, ref int count)
if (itemCount.HasValue) if (itemCount.HasValue)
{ {
long i64; long i64;
if (!itemCount.TryGetInt64(out i64)) throw new RedisConnectionException(ConnectionFailureType.ProtocolFailure, "Invalid array length"); if (!itemCount.TryGetInt64(out i64)) throw ExceptionFactory.ConnectionFailure(multiplexer.IncludeDetailInExceptions, ConnectionFailureType.ProtocolFailure, "Invalid array length", bridge.ServerEndPoint);
int itemCountActual = checked((int)i64); int itemCountActual = checked((int)i64);
if (itemCountActual == 0) return RawResult.EmptyArray; if (itemCountActual == 0) return RawResult.EmptyArray;
...@@ -764,7 +764,7 @@ private RawResult ReadBulkString(byte[] buffer, ref int offset, ref int count) ...@@ -764,7 +764,7 @@ private RawResult ReadBulkString(byte[] buffer, ref int offset, ref int count)
if (prefix.HasValue) if (prefix.HasValue)
{ {
long i64; long i64;
if (!prefix.TryGetInt64(out i64)) throw new RedisConnectionException(ConnectionFailureType.ProtocolFailure, "Invalid bulk string length"); if (!prefix.TryGetInt64(out i64)) throw ExceptionFactory.ConnectionFailure(multiplexer.IncludeDetailInExceptions, ConnectionFailureType.ProtocolFailure, "Invalid bulk string length", bridge.ServerEndPoint);
int bodySize = checked((int)i64); int bodySize = checked((int)i64);
if (bodySize < 0) if (bodySize < 0)
{ {
...@@ -774,7 +774,7 @@ private RawResult ReadBulkString(byte[] buffer, ref int offset, ref int count) ...@@ -774,7 +774,7 @@ private RawResult ReadBulkString(byte[] buffer, ref int offset, ref int count)
{ {
if (buffer[offset + bodySize] != '\r' || buffer[offset + bodySize + 1] != '\n') if (buffer[offset + bodySize] != '\r' || buffer[offset + bodySize + 1] != '\n')
{ {
throw new RedisConnectionException(ConnectionFailureType.ProtocolFailure, "Invalid bulk string terminator"); throw ExceptionFactory.ConnectionFailure(multiplexer.IncludeDetailInExceptions, ConnectionFailureType.ProtocolFailure, "Invalid bulk string terminator", bridge.ServerEndPoint);
} }
var result = new RawResult(ResultType.BulkString, buffer, offset, bodySize); var result = new RawResult(ResultType.BulkString, buffer, offset, bodySize);
offset += bodySize + 2; offset += bodySize + 2;
......
...@@ -30,13 +30,13 @@ public void Execute() ...@@ -30,13 +30,13 @@ public void Execute()
if (server == null) if (server == null)
{ {
FailNoServer(snapshot); FailNoServer(snapshot);
throw ExceptionFactory.NoConnectionAvailable(message.Command); throw ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, server);
} }
var bridge = server.GetBridge(message.Command); var bridge = server.GetBridge(message.Command);
if (bridge == null) if (bridge == null)
{ {
FailNoServer(snapshot); FailNoServer(snapshot);
throw ExceptionFactory.NoConnectionAvailable(message.Command); throw ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, server);
} }
// identity a list // identity a list
......
...@@ -1553,7 +1553,7 @@ private Message GetSortedSetAddMessage(RedisKey destination, RedisKey key, long ...@@ -1553,7 +1553,7 @@ private Message GetSortedSetAddMessage(RedisKey destination, RedisKey key, long
// because we are using STORE, we need to push this to a master // because we are using STORE, we need to push this to a master
if (Message.GetMasterSlaveFlags(flags) == CommandFlags.DemandSlave) if (Message.GetMasterSlaveFlags(flags) == CommandFlags.DemandSlave)
{ {
throw ExceptionFactory.MasterOnly(RedisCommand.SORT); throw ExceptionFactory.MasterOnly(multiplexer.IncludeDetailInExceptions, RedisCommand.SORT, null, null);
} }
flags = Message.SetMasterSlaveFlags(flags, CommandFlags.DemandMaster); flags = Message.SetMasterSlaveFlags(flags, CommandFlags.DemandMaster);
values.Add(RedisLiterals.STORE); values.Add(RedisLiterals.STORE);
......
...@@ -286,14 +286,14 @@ public Task<bool> ScriptExistsAsync(byte[] sha1, CommandFlags flags = CommandFla ...@@ -286,14 +286,14 @@ public Task<bool> ScriptExistsAsync(byte[] sha1, CommandFlags flags = CommandFla
public void ScriptFlush(CommandFlags flags = CommandFlags.None) public void ScriptFlush(CommandFlags flags = CommandFlags.None)
{ {
if (!multiplexer.RawConfig.AllowAdmin) throw ExceptionFactory.AdminModeNotEnabled(RedisCommand.SCRIPT); if (!multiplexer.RawConfig.AllowAdmin) throw ExceptionFactory.AdminModeNotEnabled(multiplexer.IncludeDetailInExceptions, RedisCommand.SCRIPT, null, server);
var msg = Message.Create(-1, flags, RedisCommand.SCRIPT, RedisLiterals.FLUSH); var msg = Message.Create(-1, flags, RedisCommand.SCRIPT, RedisLiterals.FLUSH);
ExecuteSync(msg, ResultProcessor.DemandOK); ExecuteSync(msg, ResultProcessor.DemandOK);
} }
public Task ScriptFlushAsync(CommandFlags flags = CommandFlags.None) public Task ScriptFlushAsync(CommandFlags flags = CommandFlags.None)
{ {
if (!multiplexer.RawConfig.AllowAdmin) throw ExceptionFactory.AdminModeNotEnabled(RedisCommand.SCRIPT); if (!multiplexer.RawConfig.AllowAdmin) throw ExceptionFactory.AdminModeNotEnabled(multiplexer.IncludeDetailInExceptions, RedisCommand.SCRIPT, null, server);
var msg = Message.Create(-1, flags, RedisCommand.SCRIPT, RedisLiterals.FLUSH); var msg = Message.Create(-1, flags, RedisCommand.SCRIPT, RedisLiterals.FLUSH);
return ExecuteAsync(msg, ResultProcessor.DemandOK); return ExecuteAsync(msg, ResultProcessor.DemandOK);
} }
...@@ -472,7 +472,7 @@ internal override Task<T> ExecuteAsync<T>(Message message, ResultProcessor<T> pr ...@@ -472,7 +472,7 @@ internal override Task<T> ExecuteAsync<T>(Message message, ResultProcessor<T> pr
// no need to deny exec-sync here; will be complete before they see if // no need to deny exec-sync here; will be complete before they see if
var tcs = TaskSource.Create<T>(asyncState); var tcs = TaskSource.Create<T>(asyncState);
ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(message.Command)); ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, server));
return tcs.Task; return tcs.Task;
} }
return base.ExecuteAsync<T>(message, processor, server); return base.ExecuteAsync<T>(message, processor, server);
...@@ -485,7 +485,7 @@ internal override T ExecuteSync<T>(Message message, ResultProcessor<T> processor ...@@ -485,7 +485,7 @@ internal override T ExecuteSync<T>(Message message, ResultProcessor<T> processor
if (!server.IsConnected) if (!server.IsConnected)
{ {
if (message == null || message.IsFireAndForget) return default(T); if (message == null || message.IsFireAndForget) return default(T);
throw ExceptionFactory.NoConnectionAvailable(message.Command); throw ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, server);
} }
return base.ExecuteSync<T>(message, processor, server); return base.ExecuteSync<T>(message, processor, server);
} }
......
...@@ -341,7 +341,7 @@ internal Task<T> QueueDirectAsync<T>(Message message, ResultProcessor<T> process ...@@ -341,7 +341,7 @@ internal Task<T> QueueDirectAsync<T>(Message message, ResultProcessor<T> process
message.SetSource(processor, source); message.SetSource(processor, source);
if(!(bridge ?? GetBridge(message.Command)).TryEnqueue(message, isSlave)) if(!(bridge ?? GetBridge(message.Command)).TryEnqueue(message, isSlave))
{ {
ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(message.Command)); ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, this));
} }
return tcs.Task; return tcs.Task;
} }
......
...@@ -111,7 +111,7 @@ public ServerEndPoint Select(Message message) ...@@ -111,7 +111,7 @@ public ServerEndPoint Select(Message message)
if (serverType == ServerType.Cluster) if (serverType == ServerType.Cluster)
{ {
slot = message.GetHashSlot(this); slot = message.GetHashSlot(this);
if (slot == MultipleSlots) throw ExceptionFactory.MultiSlot(); if (slot == MultipleSlots) throw ExceptionFactory.MultiSlot(multiplexer.IncludeDetailInExceptions, message);
} }
return Select(slot, message.Command, message.Flags); return Select(slot, message.Command, message.Flags);
} }
......
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