public void TestDoesNotThrowExceptionWhenEverythingIsKosherWithAWriteConcernResult() { var response = new BsonDocument { { "n", 1 }, { "connectionId", 1 }, { "ok", 1 } }; var writeConcernResult = new WriteConcernResult(response); writeConcernResult.ServerInstance = _primary; var ex = ExceptionMapper.Map(writeConcernResult); Assert.IsNull(ex); }
private CursorBatch <TDocument> ProcessReply(ConnectionId connectionId, ReplyMessage <TDocument> reply) { if (reply.CursorNotFound) { throw new MongoCursorNotFoundException(connectionId, _cursorId, _query); } if (reply.QueryFailure) { var failureDocument = reply.QueryFailureDocument; var errorMessage = string.Format("GetMore QueryFailure: {0}.", failureDocument); throw ExceptionMapper.Map(connectionId, failureDocument) ?? new MongoQueryException(connectionId, errorMessage, _query, failureDocument); } return(new CursorBatch <TDocument>(reply.CursorId, reply.Documents)); }
public async Task <CursorBatch <TDocument> > ExecuteAsync(IConnection connection, TimeSpan timeout, CancellationToken cancellationToken) { var slidingTimeout = new SlidingTimeout(timeout); var message = CreateMessage(); await connection.SendMessageAsync(message, _messageEncoderSettings, slidingTimeout, cancellationToken); var reply = await connection.ReceiveMessageAsync <TDocument>(message.RequestId, _serializer, _messageEncoderSettings, slidingTimeout, cancellationToken); if (reply.QueryFailure) { var failureDocument = reply.QueryFailureDocument; var errorMessage = string.Format("GetMore QueryFailure: {0}.", failureDocument); throw ExceptionMapper.Map(failureDocument) ?? new MongoQueryException(errorMessage, _query, failureDocument); } return(new CursorBatch <TDocument>(reply.CursorId, reply.Documents)); }
public void TestThrowsWriteConcernExceptionWhenOkButHasLastErrorMessage() { var response = new BsonDocument { { "err", "oops" }, { "code", 20 }, { "n", 0 }, { "connectionId", 1 }, { "ok", 1 } }; var writeConcernResult = new WriteConcernResult(response); var ex = ExceptionMapper.Map(writeConcernResult); Assert.IsNotNull(ex); Assert.IsInstanceOf <WriteConcernException>(ex); }
public void TestThrowsDuplicateKeyExceptionForMongod(int code) { var response = new BsonDocument { { "ok", 1 }, { "err", string.Format("E{0} duplicate key error index: test.foo.$_id_ dup key: {{ : 1.0 }}", code) }, { "code", code }, { "n", 0 }, { "connectionId", 1 } }; var writeConcernResult = new WriteConcernResult(response); var ex = ExceptionMapper.Map(writeConcernResult); Assert.IsNotNull(ex); Assert.IsInstanceOf <MongoDuplicateKeyException>(ex); }
public void TestThrowsWriteConcernExceptionWhenNotOk() { var response = new BsonDocument { { "err", "oops" }, { "code", 20 }, { "n", 0 }, { "connectionId", 1 }, { "ok", 0 } }; var writeConcernResult = new WriteConcernResult(response); writeConcernResult.ServerInstance = _primary; var ex = ExceptionMapper.Map(writeConcernResult); Assert.IsNotNull(ex); Assert.IsInstanceOf <WriteConcernException>(ex); }
private CursorBatch <TDocument> ProcessReply(ReplyMessage <TDocument> reply) { if (reply.QueryFailure) { var document = reply.QueryFailureDocument; var mappedException = ExceptionMapper.Map(document); if (mappedException != null) { throw mappedException; } var err = document.GetValue("$err", "Unknown error."); var message = string.Format("QueryFailure flag was {0} (response was {1}).", err, document.ToJson()); throw new MongoQueryException(message, _query, document); } return(new CursorBatch <TDocument>(reply.CursorId, reply.Documents)); }
protected WriteConcernResult ReadWriteConcernResult(MongoConnection connection, SendMessageWithWriteConcernResult sendMessageResult) { var writeConcernResultSerializer = BsonSerializer.LookupSerializer(typeof(WriteConcernResult)); var replyMessage = connection.ReceiveMessage <WriteConcernResult>(ReaderSettings, writeConcernResultSerializer, null); if (replyMessage.NumberReturned == 0) { throw new MongoCommandException("Command 'getLastError' failed. No response returned"); } var writeConcernResult = replyMessage.Documents[0]; writeConcernResult.Command = sendMessageResult.GetLastErrorCommand; var mappedException = ExceptionMapper.Map(writeConcernResult); if (mappedException != null) { throw mappedException; } return(writeConcernResult); }
/// <summary> /// If error results exist in the context, maps each error code to a specific exception /// type, then builds and throws a <see cref="MultiStatusException{T}"/>, with specific /// exceptions nested within. /// </summary> /// <typeparam name="T">The type of data entity.</typeparam> /// <param name="context">The object of state through the pipeline.</param> /// <param name="logger">The logging instance.</param> /// <param name="cancellationToken"> /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. /// </param> /// <returns>The completed asynchronous task.</returns> protected override Task _ProcessAsync <T>( PipelineContext <T> context, ILogger logger, CancellationToken cancellationToken) { if (context.Results == null || !context.Results.ErrorItems.Any()) { return(Task.CompletedTask); } var exceptions = new List <ApiException>(); foreach (ErrorItem <T> errorItem in context.Results.ErrorItems) { exceptions.Add(ExceptionMapper.Map(errorItem.Code, errorItem.Message, errorItem.Extra)); } throw new MultiStatusException <T>( "One or more items in the batch failed. See inner exception for details.", new AggregateException(exceptions), context.Results); }
// public methods public Exception ToWriteConcernException(ConnectionId connectionId, MongoBulkWriteOperationException bulkWriteException) { var writeConcernResult = ToWriteConcernResult(bulkWriteException.Result, bulkWriteException); var exception = ExceptionMapper.Map(connectionId, writeConcernResult.Response); if (exception == null) { exception = ExceptionMapper.Map(connectionId, writeConcernResult); } if (exception == null) { exception = new MongoWriteConcernException(connectionId, bulkWriteException.Message, writeConcernResult); } var writeConcernException = exception as MongoWriteConcernException; if (writeConcernException != null) { writeConcernException.Data["results"] = new List <WriteConcernResult>(new[] { writeConcernResult }); } return(exception); // usually a WriteConcernException unless ExceptionMapper chose a different type }
private CursorBatch <TDocument> ProcessReply(ConnectionId connectionId, ReplyMessage <TDocument> reply) { if (reply.QueryFailure) { var response = reply.QueryFailureDocument; var notPrimaryOrNodeIsRecoveringException = ExceptionMapper.MapNotPrimaryOrNodeIsRecovering(connectionId, response, "$err"); if (notPrimaryOrNodeIsRecoveringException != null) { throw notPrimaryOrNodeIsRecoveringException; } var mappedException = ExceptionMapper.Map(connectionId, response); if (mappedException != null) { throw mappedException; } var message = string.Format("QueryFailure flag was true (response was {0}).", response.ToJson()); throw new MongoQueryException(connectionId, message, _query, response); } return(new CursorBatch <TDocument>(reply.CursorId, reply.Documents)); }
// internal methods internal void ReadFrom(BsonBuffer buffer, IBsonSerializationOptions serializationOptions) { if (serializationOptions == null && typeof(TDocument) == typeof(BsonDocument)) { serializationOptions = DocumentSerializationOptions.AllowDuplicateNamesInstance; } var messageStartPosition = buffer.Position; ReadMessageHeaderFrom(buffer); _responseFlags = (ResponseFlags)buffer.ReadInt32(); _cursorId = buffer.ReadInt64(); _startingFrom = buffer.ReadInt32(); _numberReturned = buffer.ReadInt32(); if ((_responseFlags & ResponseFlags.CursorNotFound) != 0) { throw new MongoQueryException("Cursor not found."); } if ((_responseFlags & ResponseFlags.QueryFailure) != 0) { BsonDocument document; using (BsonReader bsonReader = new BsonBinaryReader(buffer, false, _readerSettings)) { document = (BsonDocument)BsonDocumentSerializer.Instance.Deserialize(bsonReader, typeof(BsonDocument), null); } var mappedException = ExceptionMapper.Map(document); if (mappedException != null) { throw mappedException; } var err = document.GetValue("$err", "Unknown error."); var message = string.Format("QueryFailure flag was {0} (response was {1}).", err, document.ToJson()); throw new MongoQueryException(message, document); } _documents = new List <TDocument>(_numberReturned); for (int i = 0; i < _numberReturned; i++) { BsonBuffer sliceBuffer; if (buffer.ByteBuffer is MultiChunkBuffer) { // we can use slightly faster SingleChunkBuffers for all documents that don't span chunk boundaries var position = buffer.Position; var length = buffer.ReadInt32(); var slice = buffer.ByteBuffer.GetSlice(position, length); buffer.Position = position + length; sliceBuffer = new BsonBuffer(slice, true); } else { sliceBuffer = new BsonBuffer(buffer.ByteBuffer, false); } using (var bsonReader = new BsonBinaryReader(sliceBuffer, true, _readerSettings)) { var document = (TDocument)_serializer.Deserialize(bsonReader, typeof(TDocument), serializationOptions); _documents.Add(document); } } }
private TCommandResult ProcessReply(ConnectionId connectionId, ReplyMessage <RawBsonDocument> reply) { if (reply.NumberReturned == 0) { throw new MongoCommandException(connectionId, "Command returned no documents.", _command); } if (reply.NumberReturned > 1) { throw new MongoCommandException(connectionId, "Command returned multiple documents.", _command); } if (reply.QueryFailure) { var failureDocument = reply.QueryFailureDocument; throw ExceptionMapper.Map(connectionId, failureDocument) ?? new MongoCommandException(connectionId, "Command failed.", _command, failureDocument); } using (var rawDocument = reply.Documents[0]) { var binaryReaderSettings = new BsonBinaryReaderSettings(); if (_messageEncoderSettings != null) { binaryReaderSettings.Encoding = _messageEncoderSettings.GetOrDefault <UTF8Encoding>(MessageEncoderSettingsName.ReadEncoding, Utf8Encodings.Strict); #pragma warning disable 618 if (BsonDefaults.GuidRepresentationMode == GuidRepresentationMode.V2) { binaryReaderSettings.GuidRepresentation = _messageEncoderSettings.GetOrDefault <GuidRepresentation>(MessageEncoderSettingsName.GuidRepresentation, GuidRepresentation.CSharpLegacy); } #pragma warning restore 618 } ; BsonValue clusterTime; if (rawDocument.TryGetValue("$clusterTime", out clusterTime)) { // note: we are assuming that _session is an instance of ClusterClockAdvancingClusterTime // and that calling _session.AdvanceClusterTime will have the side effect of advancing the cluster's ClusterTime also var materializedClusterTime = ((RawBsonDocument)clusterTime).Materialize(binaryReaderSettings); _session.AdvanceClusterTime(materializedClusterTime); } BsonValue operationTime; if (rawDocument.TryGetValue("operationTime", out operationTime)) { _session.AdvanceOperationTime(operationTime.AsBsonTimestamp); } if (!rawDocument.GetValue("ok", false).ToBoolean()) { var materializedDocument = rawDocument.Materialize(binaryReaderSettings); var commandName = _command.GetElement(0).Name; if (commandName == "$query") { commandName = _command["$query"].AsBsonDocument.GetElement(0).Name; } var notPrimaryOrNodeIsRecoveringException = ExceptionMapper.MapNotPrimaryOrNodeIsRecovering(connectionId, _command, materializedDocument, "errmsg"); if (notPrimaryOrNodeIsRecoveringException != null) { throw notPrimaryOrNodeIsRecoveringException; } string message; BsonValue errmsgBsonValue; if (materializedDocument.TryGetValue("errmsg", out errmsgBsonValue) && errmsgBsonValue.IsString) { var errmsg = errmsgBsonValue.ToString(); message = string.Format("Command {0} failed: {1}.", commandName, errmsg); } else { message = string.Format("Command {0} failed.", commandName); } var mappedException = ExceptionMapper.Map(connectionId, materializedDocument); if (mappedException != null) { throw mappedException; } throw new MongoCommandException(connectionId, message, _command, materializedDocument); } if (rawDocument.Contains("writeConcernError")) { var materializedDocument = rawDocument.Materialize(binaryReaderSettings); var writeConcernError = materializedDocument["writeConcernError"].AsBsonDocument; var message = writeConcernError.AsBsonDocument.GetValue("errmsg", null)?.AsString; var writeConcernResult = new WriteConcernResult(materializedDocument); throw new MongoWriteConcernException(connectionId, message, writeConcernResult); } using (var stream = new ByteBufferStream(rawDocument.Slice, ownsBuffer: false)) { var encoderFactory = new BinaryMessageEncoderFactory(stream, _messageEncoderSettings); var encoder = (ReplyMessageBinaryEncoder <TCommandResult>)encoderFactory.GetReplyMessageEncoder <TCommandResult>(_resultSerializer); using (var reader = encoder.CreateBinaryReader()) { var context = BsonDeserializationContext.CreateRoot(reader); return(_resultSerializer.Deserialize(context)); } } } }
public void ExceptionMapper_MapsServerExceptionsAsExpected() { Assert.IsInstanceOfType(ExceptionMapper.Map(500), typeof(InternalServerException)); Assert.IsInstanceOfType(ExceptionMapper.Map(501), typeof(MethodNotImplementedException)); Assert.IsInstanceOfType(ExceptionMapper.Map(503), typeof(ServiceUnavailableException)); }
private TCommandResult ProcessReply(ConnectionId connectionId, ReplyMessage <RawBsonDocument> reply) { if (reply.NumberReturned == 0) { throw new MongoCommandException(connectionId, "Command returned no documents.", _command); } if (reply.NumberReturned > 1) { throw new MongoCommandException(connectionId, "Command returned multiple documents.", _command); } if (reply.QueryFailure) { var failureDocument = reply.QueryFailureDocument; throw ExceptionMapper.Map(connectionId, failureDocument) ?? new MongoCommandException(connectionId, "Command failed.", _command, failureDocument); } using (var rawDocument = reply.Documents[0]) { if (!rawDocument.GetValue("ok", false).ToBoolean()) { var binaryReaderSettings = new BsonBinaryReaderSettings(); if (_messageEncoderSettings != null) { binaryReaderSettings.Encoding = _messageEncoderSettings.GetOrDefault <UTF8Encoding>(MessageEncoderSettingsName.ReadEncoding, Utf8Encodings.Strict); binaryReaderSettings.GuidRepresentation = _messageEncoderSettings.GetOrDefault <GuidRepresentation>(MessageEncoderSettingsName.GuidRepresentation, GuidRepresentation.CSharpLegacy); } ; var materializedDocument = rawDocument.Materialize(binaryReaderSettings); var commandName = _command.GetElement(0).Name; if (commandName == "$query") { commandName = _command["$query"].AsBsonDocument.GetElement(0).Name; } var notPrimaryOrNodeIsRecoveringException = ExceptionMapper.MapNotPrimaryOrNodeIsRecovering(connectionId, materializedDocument, "errmsg"); if (notPrimaryOrNodeIsRecoveringException != null) { throw notPrimaryOrNodeIsRecoveringException; } string message; BsonValue errmsgBsonValue; if (materializedDocument.TryGetValue("errmsg", out errmsgBsonValue) && errmsgBsonValue.IsString) { var errmsg = errmsgBsonValue.ToString(); message = string.Format("Command {0} failed: {1}.", commandName, errmsg); } else { message = string.Format("Command {0} failed.", commandName); } var mappedException = ExceptionMapper.Map(connectionId, materializedDocument); if (mappedException != null) { throw mappedException; } throw new MongoCommandException(connectionId, message, _command, materializedDocument); } using (var stream = new ByteBufferStream(rawDocument.Slice, ownsBuffer: false)) { var encoderFactory = new BinaryMessageEncoderFactory(stream, _messageEncoderSettings); var encoder = (ReplyMessageBinaryEncoder <TCommandResult>)encoderFactory.GetReplyMessageEncoder <TCommandResult>(_resultSerializer); using (var reader = encoder.CreateBinaryReader()) { var context = BsonDeserializationContext.CreateRoot(reader); return(_resultSerializer.Deserialize(context)); } } } }
private TCommandResult ProcessResponse(ConnectionId connectionId, CommandMessage responseMessage) { using (new CommandMessageDisposer(responseMessage)) { var rawDocument = responseMessage.Sections.OfType <Type0CommandMessageSection <RawBsonDocument> >().Single().Document; var binaryReaderSettings = new BsonBinaryReaderSettings(); if (_messageEncoderSettings != null) { binaryReaderSettings.Encoding = _messageEncoderSettings.GetOrDefault <UTF8Encoding>(MessageEncoderSettingsName.ReadEncoding, Utf8Encodings.Strict); binaryReaderSettings.GuidRepresentation = _messageEncoderSettings.GetOrDefault <GuidRepresentation>(MessageEncoderSettingsName.GuidRepresentation, GuidRepresentation.CSharpLegacy); } ; BsonValue clusterTime; if (rawDocument.TryGetValue("$clusterTime", out clusterTime)) { // note: we are assuming that _session is an instance of ClusterClockAdvancingClusterTime // and that calling _session.AdvanceClusterTime will have the side effect of advancing the cluster's ClusterTime also var materializedClusterTime = ((RawBsonDocument)clusterTime).Materialize(binaryReaderSettings); _session.AdvanceClusterTime(materializedClusterTime); } BsonValue operationTime; if (rawDocument.TryGetValue("operationTime", out operationTime)) { _session.AdvanceOperationTime(operationTime.AsBsonTimestamp); } if (!rawDocument.GetValue("ok", false).ToBoolean()) { var materializedDocument = rawDocument.Materialize(binaryReaderSettings); var commandName = _command.GetElement(0).Name; if (commandName == "$query") { commandName = _command["$query"].AsBsonDocument.GetElement(0).Name; } var notPrimaryOrNodeIsRecoveringException = ExceptionMapper.MapNotPrimaryOrNodeIsRecovering(connectionId, materializedDocument, "errmsg"); if (notPrimaryOrNodeIsRecoveringException != null) { throw notPrimaryOrNodeIsRecoveringException; } var mappedException = ExceptionMapper.Map(connectionId, materializedDocument); if (mappedException != null) { throw mappedException; } string message; BsonValue errmsgBsonValue; if (materializedDocument.TryGetValue("errmsg", out errmsgBsonValue) && errmsgBsonValue.IsString) { var errmsg = errmsgBsonValue.ToString(); message = string.Format("Command {0} failed: {1}.", commandName, errmsg); } else { message = string.Format("Command {0} failed.", commandName); } throw new MongoCommandException(connectionId, message, _command, materializedDocument); } using (var stream = new ByteBufferStream(rawDocument.Slice, ownsBuffer: false)) { using (var reader = new BsonBinaryReader(stream, binaryReaderSettings)) { var context = BsonDeserializationContext.CreateRoot(reader); return(_resultSerializer.Deserialize(context)); } } } }
public override void When() { ActualResult = ExceptionMapper.Map(Input); }
public void ExceptionMapper_MapsUnmappedExceptionsAsExpected() { Assert.IsInstanceOfType(ExceptionMapper.Map(999), typeof(UnmappedApiException)); }
private TCommandResult ProcessResponse(ConnectionId connectionId, CommandMessage responseMessage) { using (new CommandMessageDisposer(responseMessage)) { var rawDocument = responseMessage.Sections.OfType <Type0CommandMessageSection <RawBsonDocument> >().Single().Document; var binaryReaderSettings = new BsonBinaryReaderSettings(); if (_messageEncoderSettings != null) { binaryReaderSettings.Encoding = _messageEncoderSettings.GetOrDefault <UTF8Encoding>(MessageEncoderSettingsName.ReadEncoding, Utf8Encodings.Strict); #pragma warning disable 618 if (BsonDefaults.GuidRepresentationMode == GuidRepresentationMode.V2) { binaryReaderSettings.GuidRepresentation = _messageEncoderSettings.GetOrDefault <GuidRepresentation>(MessageEncoderSettingsName.GuidRepresentation, GuidRepresentation.CSharpLegacy); } #pragma warning restore 618 } ; BsonValue clusterTime; if (rawDocument.TryGetValue("$clusterTime", out clusterTime)) { // note: we are assuming that _session is an instance of ClusterClockAdvancingClusterTime // and that calling _session.AdvanceClusterTime will have the side effect of advancing the cluster's ClusterTime also var materializedClusterTime = ((RawBsonDocument)clusterTime).Materialize(binaryReaderSettings); _session.AdvanceClusterTime(materializedClusterTime); } BsonValue operationTime; if (rawDocument.TryGetValue("operationTime", out operationTime)) { _session.AdvanceOperationTime(operationTime.AsBsonTimestamp); } if (rawDocument.GetValue("ok", false).ToBoolean()) { if (rawDocument.TryGetValue("recoveryToken", out var rawRecoveryToken)) { var recoveryToken = ((RawBsonDocument)rawRecoveryToken).Materialize(binaryReaderSettings); _session.CurrentTransaction.RecoveryToken = recoveryToken; } } else { var materializedDocument = rawDocument.Materialize(binaryReaderSettings); var commandName = _command.GetElement(0).Name; if (commandName == "$query") { commandName = _command["$query"].AsBsonDocument.GetElement(0).Name; } var notPrimaryOrNodeIsRecoveringException = ExceptionMapper.MapNotPrimaryOrNodeIsRecovering(connectionId, _command, materializedDocument, "errmsg"); if (notPrimaryOrNodeIsRecoveringException != null) { throw notPrimaryOrNodeIsRecoveringException; } var mappedException = ExceptionMapper.Map(connectionId, materializedDocument); if (mappedException != null) { throw mappedException; } string message; BsonValue errmsgBsonValue; if (materializedDocument.TryGetValue("errmsg", out errmsgBsonValue) && errmsgBsonValue.IsString) { var errmsg = errmsgBsonValue.ToString(); message = string.Format("Command {0} failed: {1}.", commandName, errmsg); } else { message = string.Format("Command {0} failed.", commandName); } var exception = new MongoCommandException(connectionId, message, _command, materializedDocument); // https://jira.mongodb.org/browse/CSHARP-2678 if (IsRetryableWriteExceptionAndDeploymentDoesNotSupportRetryableWrites(exception)) { throw WrapNotSupportedRetryableWriteException(exception); } else { throw exception; } } if (rawDocument.Contains("writeConcernError")) { var materializedDocument = rawDocument.Materialize(binaryReaderSettings); var writeConcernError = materializedDocument["writeConcernError"].AsBsonDocument; var message = writeConcernError.AsBsonDocument.GetValue("errmsg", null)?.AsString; var writeConcernResult = new WriteConcernResult(materializedDocument); throw new MongoWriteConcernException(connectionId, message, writeConcernResult); } using (var stream = new ByteBufferStream(rawDocument.Slice, ownsBuffer: false)) { using (var reader = new BsonBinaryReader(stream, binaryReaderSettings)) { var context = BsonDeserializationContext.CreateRoot(reader); return(_resultSerializer.Deserialize(context)); } } } }