MongoBulkWriteException.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /* Copyright 2010-present MongoDB Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Linq;
  18. #if NET452
  19. using System.Runtime.Serialization;
  20. #endif
  21. using System.Text;
  22. using MongoDB.Driver.Core.Connections;
  23. using MongoDB.Driver.Core.Operations;
  24. using MongoDB.Driver.Support;
  25. namespace MongoDB.Driver
  26. {
  27. /// <summary>
  28. /// Represents a bulk write exception.
  29. /// </summary>
  30. #if NET452
  31. [Serializable]
  32. #endif
  33. public abstract class MongoBulkWriteException : MongoServerException
  34. {
  35. // private fields
  36. private readonly WriteConcernError _writeConcernError;
  37. private readonly IReadOnlyList<BulkWriteError> _writeErrors;
  38. /// <summary>
  39. /// Initializes a new instance of the <see cref="MongoBulkWriteException" /> class.
  40. /// </summary>
  41. /// <param name="connectionId">The connection identifier.</param>
  42. /// <param name="writeErrors">The write errors.</param>
  43. /// <param name="writeConcernError">The write concern error.</param>
  44. public MongoBulkWriteException(
  45. ConnectionId connectionId,
  46. IEnumerable<BulkWriteError> writeErrors,
  47. WriteConcernError writeConcernError)
  48. : base(connectionId, message: FormatMessage(writeErrors, writeConcernError))
  49. {
  50. _writeErrors = writeErrors.ToList();
  51. _writeConcernError = writeConcernError;
  52. }
  53. #if NET452
  54. /// <summary>
  55. /// Initializes a new instance of the MongoQueryException class (this overload supports deserialization).
  56. /// </summary>
  57. /// <param name="info">The SerializationInfo.</param>
  58. /// <param name="context">The StreamingContext.</param>
  59. public MongoBulkWriteException(SerializationInfo info, StreamingContext context)
  60. : base(info, context)
  61. {
  62. _writeConcernError = (WriteConcernError)info.GetValue("_writeConcernError", typeof(WriteConcernError));
  63. _writeErrors = (IReadOnlyList<BulkWriteError>)info.GetValue("_writeErrors", typeof(IReadOnlyList<BulkWriteError>));
  64. }
  65. #endif
  66. // properties
  67. /// <summary>
  68. /// Gets the write concern error.
  69. /// </summary>
  70. public WriteConcernError WriteConcernError
  71. {
  72. get { return _writeConcernError; }
  73. }
  74. /// <summary>
  75. /// Gets the write errors.
  76. /// </summary>
  77. public IReadOnlyList<BulkWriteError> WriteErrors
  78. {
  79. get { return _writeErrors; }
  80. }
  81. // methods
  82. #if NET452
  83. /// <summary>
  84. /// Gets the object data.
  85. /// </summary>
  86. /// <param name="info">The information.</param>
  87. /// <param name="context">The context.</param>
  88. public override void GetObjectData(SerializationInfo info, StreamingContext context)
  89. {
  90. base.GetObjectData(info, context);
  91. info.AddValue("_writeConcernError", _writeConcernError);
  92. info.AddValue("_writeErrors", _writeErrors);
  93. }
  94. #endif
  95. // private static methods
  96. private static string FormatMessage(IEnumerable<BulkWriteError> writeErrors, WriteConcernError writeConcernError)
  97. {
  98. var sb = new StringBuilder("A bulk write operation resulted in one or more errors.");
  99. if (writeErrors != null)
  100. {
  101. foreach (var writeError in writeErrors)
  102. {
  103. sb.AppendLine().Append(" " + writeError.Message);
  104. }
  105. }
  106. if (writeConcernError != null)
  107. {
  108. sb.AppendLine().Append(" " + writeConcernError.Message);
  109. }
  110. return sb.ToString();
  111. }
  112. }
  113. /// <summary>
  114. /// Represents a bulk write exception.
  115. /// </summary>
  116. /// <typeparam name="TDocument">The type of the document.</typeparam>
  117. #if NET452
  118. [Serializable]
  119. #endif
  120. public sealed class MongoBulkWriteException<TDocument> : MongoBulkWriteException
  121. {
  122. // private fields
  123. private readonly BulkWriteResult<TDocument> _result;
  124. private readonly IReadOnlyList<WriteModel<TDocument>> _unprocessedRequests;
  125. // constructors
  126. /// <summary>
  127. /// Initializes a new instance of the <see cref="MongoBulkWriteException" /> class.
  128. /// </summary>
  129. /// <param name="connectionId">The connection identifier.</param>
  130. /// <param name="result">The result.</param>
  131. /// <param name="writeErrors">The write errors.</param>
  132. /// <param name="writeConcernError">The write concern error.</param>
  133. /// <param name="unprocessedRequests">The unprocessed requests.</param>
  134. public MongoBulkWriteException(
  135. ConnectionId connectionId,
  136. BulkWriteResult<TDocument> result,
  137. IEnumerable<BulkWriteError> writeErrors,
  138. WriteConcernError writeConcernError,
  139. IEnumerable<WriteModel<TDocument>> unprocessedRequests)
  140. : base(connectionId, writeErrors, writeConcernError)
  141. {
  142. _result = result;
  143. _unprocessedRequests = unprocessedRequests.ToList();
  144. }
  145. #if NET452
  146. /// <summary>
  147. /// Initializes a new instance of the MongoQueryException class (this overload supports deserialization).
  148. /// </summary>
  149. /// <param name="info">The SerializationInfo.</param>
  150. /// <param name="context">The StreamingContext.</param>
  151. public MongoBulkWriteException(SerializationInfo info, StreamingContext context)
  152. : base(info, context)
  153. {
  154. if (typeof(TDocument).IsSerializable)
  155. {
  156. _result = (BulkWriteResult<TDocument>)info.GetValue("_result", typeof(BulkWriteResult<TDocument>));
  157. _unprocessedRequests = (IReadOnlyList<WriteModel<TDocument>>)info.GetValue("_unprocessedRequests", typeof(IReadOnlyList<WriteModel<TDocument>>));
  158. }
  159. }
  160. #endif
  161. // public properties
  162. /// <summary>
  163. /// Gets the result of the bulk write operation.
  164. /// </summary>
  165. public BulkWriteResult<TDocument> Result
  166. {
  167. get { return _result; }
  168. }
  169. /// <summary>
  170. /// Gets the unprocessed requests.
  171. /// </summary>
  172. public IReadOnlyList<WriteModel<TDocument>> UnprocessedRequests
  173. {
  174. get { return _unprocessedRequests; }
  175. }
  176. // methods
  177. #if NET452
  178. /// <summary>
  179. /// Gets the object data.
  180. /// </summary>
  181. /// <param name="info">The information.</param>
  182. /// <param name="context">The context.</param>
  183. public override void GetObjectData(SerializationInfo info, StreamingContext context)
  184. {
  185. base.GetObjectData(info, context);
  186. if (typeof(TDocument).IsSerializable)
  187. {
  188. info.AddValue("_result", _result);
  189. info.AddValue("_unprocessedRequests", _unprocessedRequests);
  190. }
  191. }
  192. #endif
  193. // internal static methods
  194. internal static MongoBulkWriteException<TDocument> FromCore(MongoBulkWriteOperationException ex)
  195. {
  196. return new MongoBulkWriteException<TDocument>(
  197. ex.ConnectionId,
  198. BulkWriteResult<TDocument>.FromCore(ex.Result),
  199. ex.WriteErrors.Select(e => BulkWriteError.FromCore(e)),
  200. WriteConcernError.FromCore(ex.WriteConcernError),
  201. ex.UnprocessedRequests.Select(r => WriteModel<TDocument>.FromCore(r)));
  202. }
  203. internal static MongoBulkWriteException<TDocument> FromCore(MongoBulkWriteOperationException ex, IReadOnlyList<WriteModel<TDocument>> requests)
  204. {
  205. var processedRequests = ex.Result.ProcessedRequests
  206. .Select(r => new { CorrelationId = r.CorrelationId.Value, Request = requests[r.CorrelationId.Value] })
  207. .OrderBy(x => x.CorrelationId)
  208. .Select(x => x.Request);
  209. var unprocessedRequests = ex.UnprocessedRequests
  210. .Select(r => new { CorrelationId = r.CorrelationId.Value, Request = requests[r.CorrelationId.Value] })
  211. .OrderBy(x => x.CorrelationId)
  212. .Select(x => x.Request);
  213. return new MongoBulkWriteException<TDocument>(
  214. ex.ConnectionId,
  215. BulkWriteResult<TDocument>.FromCore(ex.Result, processedRequests),
  216. ex.WriteErrors.Select(e => BulkWriteError.FromCore(e)),
  217. WriteConcernError.FromCore(ex.WriteConcernError),
  218. unprocessedRequests);
  219. }
  220. }
  221. }