/* Copyright 2010-present MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.Linq; #if NET452 using System.Runtime.Serialization; #endif using System.Text; using MongoDB.Driver.Core.Connections; using MongoDB.Driver.Core.Operations; using MongoDB.Driver.Support; namespace MongoDB.Driver { /// /// Represents a bulk write exception. /// #if NET452 [Serializable] #endif public abstract class MongoBulkWriteException : MongoServerException { // private fields private readonly WriteConcernError _writeConcernError; private readonly IReadOnlyList _writeErrors; /// /// Initializes a new instance of the class. /// /// The connection identifier. /// The write errors. /// The write concern error. public MongoBulkWriteException( ConnectionId connectionId, IEnumerable writeErrors, WriteConcernError writeConcernError) : base(connectionId, message: FormatMessage(writeErrors, writeConcernError)) { _writeErrors = writeErrors.ToList(); _writeConcernError = writeConcernError; } #if NET452 /// /// Initializes a new instance of the MongoQueryException class (this overload supports deserialization). /// /// The SerializationInfo. /// The StreamingContext. public MongoBulkWriteException(SerializationInfo info, StreamingContext context) : base(info, context) { _writeConcernError = (WriteConcernError)info.GetValue("_writeConcernError", typeof(WriteConcernError)); _writeErrors = (IReadOnlyList)info.GetValue("_writeErrors", typeof(IReadOnlyList)); } #endif // properties /// /// Gets the write concern error. /// public WriteConcernError WriteConcernError { get { return _writeConcernError; } } /// /// Gets the write errors. /// public IReadOnlyList WriteErrors { get { return _writeErrors; } } // methods #if NET452 /// /// Gets the object data. /// /// The information. /// The context. public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); info.AddValue("_writeConcernError", _writeConcernError); info.AddValue("_writeErrors", _writeErrors); } #endif // private static methods private static string FormatMessage(IEnumerable writeErrors, WriteConcernError writeConcernError) { var sb = new StringBuilder("A bulk write operation resulted in one or more errors."); if (writeErrors != null) { foreach (var writeError in writeErrors) { sb.AppendLine().Append(" " + writeError.Message); } } if (writeConcernError != null) { sb.AppendLine().Append(" " + writeConcernError.Message); } return sb.ToString(); } } /// /// Represents a bulk write exception. /// /// The type of the document. #if NET452 [Serializable] #endif public sealed class MongoBulkWriteException : MongoBulkWriteException { // private fields private readonly BulkWriteResult _result; private readonly IReadOnlyList> _unprocessedRequests; // constructors /// /// Initializes a new instance of the class. /// /// The connection identifier. /// The result. /// The write errors. /// The write concern error. /// The unprocessed requests. public MongoBulkWriteException( ConnectionId connectionId, BulkWriteResult result, IEnumerable writeErrors, WriteConcernError writeConcernError, IEnumerable> unprocessedRequests) : base(connectionId, writeErrors, writeConcernError) { _result = result; _unprocessedRequests = unprocessedRequests.ToList(); } #if NET452 /// /// Initializes a new instance of the MongoQueryException class (this overload supports deserialization). /// /// The SerializationInfo. /// The StreamingContext. public MongoBulkWriteException(SerializationInfo info, StreamingContext context) : base(info, context) { if (typeof(TDocument).IsSerializable) { _result = (BulkWriteResult)info.GetValue("_result", typeof(BulkWriteResult)); _unprocessedRequests = (IReadOnlyList>)info.GetValue("_unprocessedRequests", typeof(IReadOnlyList>)); } } #endif // public properties /// /// Gets the result of the bulk write operation. /// public BulkWriteResult Result { get { return _result; } } /// /// Gets the unprocessed requests. /// public IReadOnlyList> UnprocessedRequests { get { return _unprocessedRequests; } } // methods #if NET452 /// /// Gets the object data. /// /// The information. /// The context. public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); if (typeof(TDocument).IsSerializable) { info.AddValue("_result", _result); info.AddValue("_unprocessedRequests", _unprocessedRequests); } } #endif // internal static methods internal static MongoBulkWriteException FromCore(MongoBulkWriteOperationException ex) { return new MongoBulkWriteException( ex.ConnectionId, BulkWriteResult.FromCore(ex.Result), ex.WriteErrors.Select(e => BulkWriteError.FromCore(e)), WriteConcernError.FromCore(ex.WriteConcernError), ex.UnprocessedRequests.Select(r => WriteModel.FromCore(r))); } internal static MongoBulkWriteException FromCore(MongoBulkWriteOperationException ex, IReadOnlyList> requests) { var processedRequests = ex.Result.ProcessedRequests .Select(r => new { CorrelationId = r.CorrelationId.Value, Request = requests[r.CorrelationId.Value] }) .OrderBy(x => x.CorrelationId) .Select(x => x.Request); var unprocessedRequests = ex.UnprocessedRequests .Select(r => new { CorrelationId = r.CorrelationId.Value, Request = requests[r.CorrelationId.Value] }) .OrderBy(x => x.CorrelationId) .Select(x => x.Request); return new MongoBulkWriteException( ex.ConnectionId, BulkWriteResult.FromCore(ex.Result, processedRequests), ex.WriteErrors.Select(e => BulkWriteError.FromCore(e)), WriteConcernError.FromCore(ex.WriteConcernError), unprocessedRequests); } } }