mongo 2.10.0 → 2.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a1e6b0cb6b8548601a5ad4c4758361f9815d65750b52fef6b2393eb09ab5ae4
4
- data.tar.gz: '084a8d5a64bba3ffaab853919918f9cb214754edbaec4ac22eeaee5e9954f39b'
3
+ metadata.gz: 18e71f41caf0b6b8c618c8ea7cedb903ca10248949993c6c25ebf61d6acf3bba
4
+ data.tar.gz: bd587a35aadbaf790b61c83867f276bd13858c6469fb8ef26bf3907e58a5703a
5
5
  SHA512:
6
- metadata.gz: 19fc6811951a53cfef86d647849337fb56014e97d2cf9aec0ea0de58f3525632a96e04c1f5a6ecd4f6de8f7a853faded939e59f716d9fa4a6c9ac40a7e742ce9
7
- data.tar.gz: '08ff4b626997aa23fb9db94893818e2326cc2c13032ea4dabf512628b436597f13a2c69a2693d57fd58d60208c384660b4c811ca98b8aeb1a47994b212a0dbd5'
6
+ metadata.gz: c923c55b783fb6d0a37d90116684afe65c038d1d7c06dfa1ace59a825eeee441ad7384f42ab45cb47bc7f2abedc16faef6f5f8adef68751631dcc57ddbca8be1
7
+ data.tar.gz: bff45797b2533f2d842787c9c1d63eef76deab4471244af4d759237ab122b70d3c785d2ad064bf0b79e3d045c86efa5f6f7f47e4b8cdec5607b95ffd323400d3
@@ -1,2 +1,3 @@
1
- ��B��H��\v0��m1h]CQ-Ҥق�H��_ u����l��*ί���B�|���Z9��{ҡ��<Y��
2
- h0MΓ��H��o��"w�;{c�sȄ��/��D!�)'�#�Pcf�r���R`����\'ז�S�SZD�
1
+ *܉o]���GO�=��S��rhc�ug�0D����}D����җoC&AH�N� �9)s����(��p��qodh^_���pZL)J(m�lܫ��p駴�x���#Fƻkf!��3f�j�0"ٖ|繣��Zy����?j��j�����Бd�1(2�������[D<��ޒ�9���l���m"R
2
+ �"�G�~����:��
3
+ q_���=��y=�|�Т[���-�����ވ���`��+Vf!
data.tar.gz.sig CHANGED
Binary file
@@ -23,7 +23,7 @@ require 'mongo/bulk_write/result_combiner'
23
23
  module Mongo
24
24
  class BulkWrite
25
25
  extend Forwardable
26
- include Operation::Unpinnable
26
+ include Operation::ResponseHandling
27
27
 
28
28
  # @return [ Mongo::Collection ] collection The collection.
29
29
  attr_reader :collection
@@ -12,11 +12,14 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require 'mongo/error/notable'
16
+
15
17
  module Mongo
16
18
  # Base error class for all Mongo related errors.
17
19
  #
18
20
  # @since 2.0.0
19
21
  class Error < StandardError
22
+ include Notable
20
23
 
21
24
  # The error code field.
22
25
  #
@@ -141,6 +144,7 @@ module Mongo
141
144
  end
142
145
  end
143
146
 
147
+ require 'mongo/error/auth_error'
144
148
  require 'mongo/error/sdam_error_detection'
145
149
  require 'mongo/error/parser'
146
150
  require 'mongo/error/write_retryable'
@@ -0,0 +1,29 @@
1
+ # Copyright (C) 2018-2019 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
+ module Mongo
16
+ class Error
17
+
18
+ # Raised when authentication fails.
19
+ #
20
+ # Note: This class is derived from RuntimeError for
21
+ # backwards compatibility reasons. It is subject to
22
+ # change in future major versions of the driver.
23
+ #
24
+ # @since 2.10.1
25
+ class AuthError < RuntimeError
26
+ include Notable
27
+ end
28
+ end
29
+ end
@@ -50,7 +50,7 @@ module Mongo
50
50
  else
51
51
  ''
52
52
  end
53
- self.class.name + messages
53
+ "#{self.class}: #{messages}" + notes_tail
54
54
  end
55
55
  end
56
56
  end
@@ -0,0 +1,80 @@
1
+ # Copyright (C) 2019 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
+ module Mongo
16
+ class Error < StandardError
17
+
18
+ # A module encapsulating note tracking functionality, since currently
19
+ # the driver does not have a single exception hierarchy root.
20
+ #
21
+ # @since 2.10.1
22
+ # @api private
23
+ module Notable
24
+
25
+ # Returns an array of strings with additional information about the
26
+ # exception.
27
+ #
28
+ # @return [ Array<String> ] Additional information strings.
29
+ #
30
+ # @since 2.10.1
31
+ # @api public
32
+ def notes
33
+ if @notes
34
+ @notes.dup
35
+ else
36
+ []
37
+ end
38
+ end
39
+
40
+ # @api private
41
+ def add_note(note)
42
+ unless @notes
43
+ @notes = []
44
+ end
45
+ @notes << note
46
+ end
47
+
48
+ # @api public
49
+ def message
50
+ super + notes_tail
51
+ end
52
+
53
+ # @api public
54
+ def to_s
55
+ super + notes_tail
56
+ end
57
+
58
+ # @api public
59
+ def inspect
60
+ msg = super
61
+ if msg.end_with?('>')
62
+ msg[0...msg.length-1] + notes_tail + '>'
63
+ else
64
+ msg + notes_tail
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ # @api private
71
+ def notes_tail
72
+ msg = ''
73
+ unless notes.empty?
74
+ msg += " (#{notes.join(', ')})"
75
+ end
76
+ msg
77
+ end
78
+ end
79
+ end
80
+ end
@@ -1,5 +1,6 @@
1
1
  require 'mongo/operation/result'
2
2
 
3
+ require 'mongo/operation/shared/response_handling'
3
4
  require 'mongo/operation/shared/executable'
4
5
  require 'mongo/operation/shared/executable_no_validate'
5
6
  require 'mongo/operation/shared/executable_transaction_label'
@@ -13,7 +14,6 @@ require 'mongo/operation/shared/sessions_supported'
13
14
  require 'mongo/operation/shared/causal_consistency_supported'
14
15
  require 'mongo/operation/shared/write'
15
16
  require 'mongo/operation/shared/idable'
16
- require 'mongo/operation/shared/unpinnable'
17
17
  require 'mongo/operation/shared/specifiable'
18
18
  require 'mongo/operation/shared/object_id_generator'
19
19
  require 'mongo/operation/shared/op_msg_or_command'
@@ -24,28 +24,18 @@ module Mongo
24
24
  class Command
25
25
  include Specifiable
26
26
  include Executable
27
+ include ExecutableNoValidate
27
28
  include Idable
28
29
  include Limited
29
30
  include WriteConcernSupported
30
31
  include BypassDocumentValidation
31
32
 
32
- # Execute the operation.
33
- #
34
- # @example
35
- # operation.execute(server)
36
- #
37
- # @param [ Mongo::Server ] server The server to send the operation to.
38
- #
39
- # @return [ Mongo::Operation::Insert::Result ] The operation result.
40
- #
41
- # @since 2.5.2
42
- def execute(server)
43
- result = Result.new(dispatch_message(server), @ids)
44
- process_result(result, server)
45
- end
46
-
47
33
  private
48
34
 
35
+ def get_result(server)
36
+ Result.new(dispatch_message(server), @ids)
37
+ end
38
+
49
39
  def selector(server)
50
40
  { insert: coll_name,
51
41
  documents: send(IDENTIFIER),
@@ -28,24 +28,12 @@ module Mongo
28
28
  include Executable
29
29
  include Idable
30
30
 
31
- # Execute the operation.
32
- #
33
- # @example
34
- # operation.execute(server)
35
- #
36
- # @param [ Mongo::Server ] server The server to send the operation to.
37
- #
38
- # @return [ Mongo::Operation::Insert::Result ] The operation result.
39
- #
40
- # @since 2.5.2
41
- def execute(server)
42
- result = Result.new(dispatch_message(server), @ids)
43
- process_result(result, server)
44
- result.validate!
45
- end
46
-
47
31
  private
48
32
 
33
+ def get_result(server)
34
+ Result.new(dispatch_message(server), @ids)
35
+ end
36
+
49
37
  def selector
50
38
  send(IDENTIFIER).first
51
39
  end
@@ -20,11 +20,15 @@ module Mongo
20
20
  # @since 2.5.2
21
21
  module Executable
22
22
 
23
+ include ResponseHandling
24
+
23
25
  def do_execute(server)
24
26
  unpin_maybe(session) do
25
27
  add_error_labels do
26
- get_result(server).tap do |result|
27
- process_result(result, server)
28
+ add_server_diagnostics(server) do
29
+ get_result(server).tap do |result|
30
+ process_result(result, server)
31
+ end
28
32
  end
29
33
  end
30
34
  end
@@ -32,7 +36,7 @@ module Mongo
32
36
 
33
37
  def execute(server)
34
38
  do_execute(server).tap do |result|
35
- validate_result(result)
39
+ validate_result(result, server)
36
40
  end
37
41
  end
38
42
 
@@ -0,0 +1,94 @@
1
+ # Copyright (C) 2019 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
+ module Mongo
16
+ module Operation
17
+
18
+ # Shared behavior of response handling for operations.
19
+ #
20
+ # @api private
21
+ module ResponseHandling
22
+
23
+ private
24
+
25
+ def validate_result(result, server)
26
+ unpin_maybe(session) do
27
+ add_error_labels do
28
+ add_server_diagnostics(server) do
29
+ result.validate!
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ # Adds error labels to exceptions raised in the yielded to block,
36
+ # which should perform MongoDB operations and raise Mongo::Errors on
37
+ # failure. This method handles network errors (Error::SocketError)
38
+ # and server-side errors (Error::OperationFailure); it does not
39
+ # handle server selection errors (Error::NoServerAvailable), for which
40
+ # labels are added in the server selection code.
41
+ def add_error_labels
42
+ begin
43
+ yield
44
+ rescue Mongo::Error::SocketError => e
45
+ if session && session.in_transaction? && !session.committing_transaction?
46
+ e.add_label('TransientTransactionError')
47
+ end
48
+ if session && session.committing_transaction?
49
+ e.add_label('UnknownTransactionCommitResult')
50
+ end
51
+ raise e
52
+ rescue Mongo::Error::OperationFailure => e
53
+ if session && session.committing_transaction?
54
+ if e.write_retryable? || e.wtimeout? || (e.write_concern_error? &&
55
+ !Session::UNLABELED_WRITE_CONCERN_CODES.include?(e.write_concern_error_code)
56
+ ) || e.max_time_ms_expired?
57
+ e.add_label('UnknownTransactionCommitResult')
58
+ end
59
+ end
60
+ raise e
61
+ end
62
+ end
63
+
64
+ # Unpins the session if the session is pinned and the yielded to block
65
+ # raises errors that are required to unpin the session.
66
+ #
67
+ # @note This method takes the session as an argument because this module
68
+ # is included in BulkWrite which does not store the session in the
69
+ # receiver (despite Specifiable doing so).
70
+ #
71
+ # @param [ Session | nil ] Session to consider.
72
+ def unpin_maybe(session)
73
+ yield
74
+ rescue Mongo::Error => e
75
+ if session
76
+ session.unpin_maybe(e)
77
+ end
78
+ raise
79
+ end
80
+
81
+ # Yields to the block and, if the block raises an exception, adds a note
82
+ # to the exception with the address of the specified server.
83
+ #
84
+ # This method is intended to add server address information to exceptions
85
+ # raised during execution of operations on servers.
86
+ def add_server_diagnostics(server)
87
+ yield
88
+ rescue Mongo::Error, Mongo::Error::AuthError => e
89
+ e.add_note("on #{server.address.seed}")
90
+ raise e
91
+ end
92
+ end
93
+ end
94
+ end
@@ -20,7 +20,6 @@ module Mongo
20
20
  #
21
21
  # @since 2.0.0
22
22
  module Specifiable
23
- include Unpinnable
24
23
 
25
24
  # The field for database name.
26
25
  #
@@ -565,45 +564,6 @@ module Mongo
565
564
  def acknowledged_write?
566
565
  write_concern.nil? || write_concern.acknowledged?
567
566
  end
568
-
569
- private
570
-
571
- def validate_result(result)
572
- unpin_maybe(session) do
573
- add_error_labels do
574
- result.validate!
575
- end
576
- end
577
- end
578
-
579
- # Adds error labels to exceptions raised in the yielded to block,
580
- # which should perform MongoDB operations and raise Mongo::Errors on
581
- # failure. This method handles network errors (Error::SocketError)
582
- # and server-side errors (Error::OperationFailure); it does not
583
- # handle server selection errors (Error::NoServerAvailable), for which
584
- # labels are added in the server selection code.
585
- def add_error_labels
586
- begin
587
- yield
588
- rescue Mongo::Error::SocketError => e
589
- if session && session.in_transaction? && !session.committing_transaction?
590
- e.add_label('TransientTransactionError')
591
- end
592
- if session && session.committing_transaction?
593
- e.add_label('UnknownTransactionCommitResult')
594
- end
595
- raise e
596
- rescue Mongo::Error::OperationFailure => e
597
- if session && session.committing_transaction?
598
- if e.write_retryable? || e.wtimeout? || (e.write_concern_error? &&
599
- !Session::UNLABELED_WRITE_CONCERN_CODES.include?(e.write_concern_error_code)
600
- ) || e.max_time_ms_expired?
601
- e.add_label('UnknownTransactionCommitResult')
602
- end
603
- end
604
- raise e
605
- end
606
- end
607
567
  end
608
568
  end
609
569
  end
@@ -20,6 +20,8 @@ module Mongo
20
20
  # @since 2.5.2
21
21
  module Write
22
22
 
23
+ include ResponseHandling
24
+
23
25
  # Execute the operation.
24
26
  #
25
27
  # @example
@@ -39,7 +41,7 @@ module Mongo
39
41
  else
40
42
  self.class::Command.new(spec).execute(server)
41
43
  end
42
- validate_result(result)
44
+ validate_result(result, server)
43
45
  end
44
46
 
45
47
  # Execute the bulk write operation.
@@ -206,19 +206,25 @@ module Mongo
206
206
  return legacy_write_with_retry(server, session, &block)
207
207
  end
208
208
 
209
+ txn_num = if session.in_transaction?
210
+ session.txn_num
211
+ else
212
+ session.next_txn_num
213
+ end
209
214
  begin
210
- txn_num = session.in_transaction? ? session.txn_num : session.next_txn_num
211
215
  yield(server, txn_num, false)
212
216
  rescue Error::SocketError, Error::SocketTimeoutError => e
217
+ e.add_note("attempt 1")
213
218
  if session.in_transaction? && !ending_transaction
214
- raise
219
+ raise e
215
220
  end
216
221
  retry_write(e, session, txn_num, &block)
217
222
  rescue Error::OperationFailure => e
223
+ e.add_note("attempt 1")
218
224
  if e.unsupported_retryable_write?
219
225
  raise_unsupported_error(e)
220
226
  elsif (session.in_transaction? && !ending_transaction) || !e.write_retryable?
221
- raise
227
+ raise e
222
228
  end
223
229
 
224
230
  retry_write(e, session, txn_num, &block)
@@ -274,16 +280,17 @@ module Mongo
274
280
  server ||= select_server(cluster, ServerSelector.primary, session)
275
281
  yield server
276
282
  rescue Error::OperationFailure => e
283
+ e.add_note("attempt #{attempt + 1}")
277
284
  server = nil
278
285
  if attempt > client.max_write_retries
279
- raise
286
+ raise e
280
287
  end
281
288
  if e.write_retryable? && !(session && session.in_transaction?)
282
289
  log_retry(e, message: 'Legacy write retry')
283
290
  cluster.scan!(false)
284
291
  retry
285
292
  else
286
- raise
293
+ raise e
287
294
  end
288
295
  end
289
296
  end
@@ -296,13 +303,15 @@ module Mongo
296
303
  begin
297
304
  yield server
298
305
  rescue Error::SocketError, Error::SocketTimeoutError => e
306
+ e.add_note("attempt #{attempt + 1}")
299
307
  if session.in_transaction?
300
- raise
308
+ raise e
301
309
  end
302
310
  retry_read(e, server_selector, session, &block)
303
311
  rescue Error::OperationFailure => e
312
+ e.add_note("attempt #{attempt + 1}")
304
313
  if session.in_transaction? || !e.write_retryable?
305
- raise
314
+ raise e
306
315
  end
307
316
  retry_read(e, server_selector, session, &block)
308
317
  end
@@ -315,23 +324,25 @@ module Mongo
315
324
  attempt += 1
316
325
  yield server
317
326
  rescue Error::SocketError, Error::SocketTimeoutError => e
327
+ e.add_note("attempt #{attempt + 1}")
318
328
  if attempt > client.max_read_retries || (session && session.in_transaction?)
319
- raise
329
+ raise e
320
330
  end
321
331
  log_retry(e, message: 'Legacy read retry')
322
332
  server = select_server(cluster, server_selector, session)
323
333
  retry
324
334
  rescue Error::OperationFailure => e
335
+ e.add_note("attempt #{attempt + 1}")
325
336
  if cluster.sharded? && e.retryable? && !(session && session.in_transaction?)
326
337
  if attempt > client.max_read_retries
327
- raise
338
+ raise e
328
339
  end
329
340
  log_retry(e, message: 'Legacy read retry')
330
341
  sleep(client.read_retry_interval)
331
342
  server = select_server(cluster, server_selector, session)
332
343
  retry
333
344
  else
334
- raise
345
+ raise e
335
346
  end
336
347
  end
337
348
  end
@@ -354,7 +365,8 @@ module Mongo
354
365
  def retry_read(original_error, server_selector, session, &block)
355
366
  begin
356
367
  server = select_server(cluster, server_selector, session)
357
- rescue
368
+ rescue => e
369
+ original_error.add_note("later retry failed: #{e.class}: #{e}")
358
370
  raise original_error
359
371
  end
360
372
 
@@ -363,11 +375,17 @@ module Mongo
363
375
  begin
364
376
  yield server, true
365
377
  rescue Error::SocketError, Error::SocketTimeoutError => e
378
+ e.add_note("attempt 2")
366
379
  raise e
367
380
  rescue Error::OperationFailure => e
368
- raise original_error unless e.write_retryable?
381
+ unless e.write_retryable?
382
+ original_error.add_note("later retry failed: #{e.class}: #{e}")
383
+ raise original_error
384
+ end
385
+ e.add_note("attempt 2")
369
386
  raise e
370
- rescue
387
+ rescue => e
388
+ original_error.add_note("later retry failed: #{e.class}: #{e}")
371
389
  raise original_error
372
390
  end
373
391
  end
@@ -379,15 +397,25 @@ module Mongo
379
397
  # a socket error or a not master error should have marked the respective
380
398
  # server unknown). Here we just need to wait for server selection.
381
399
  server = select_server(cluster, ServerSelector.primary, session)
382
- raise original_error unless (server.retry_writes? && txn_num)
400
+ unless server.retry_writes?
401
+ original_error.add_note('did not retry because server selected for retry does not supoprt retryable writes')
402
+ raise original_error
403
+ end
383
404
  log_retry(original_error, message: 'Write retry')
384
405
  yield(server, txn_num, true)
385
406
  rescue Error::SocketError, Error::SocketTimeoutError => e
407
+ e.add_note('attempt 2')
386
408
  raise e
387
409
  rescue Error::OperationFailure => e
388
- raise original_error unless e.write_retryable?
389
- raise e
390
- rescue
410
+ if e.write_retryable?
411
+ e.add_note('attempt 2')
412
+ raise e
413
+ else
414
+ original_error.add_note("later retry failed: #{e.class}: #{e}")
415
+ raise original_error
416
+ end
417
+ rescue => e
418
+ original_error.add_note("later retry failed: #{e.class}: #{e}")
391
419
  raise original_error
392
420
  end
393
421
 
@@ -17,5 +17,5 @@ module Mongo
17
17
  # The current version of the driver.
18
18
  #
19
19
  # @since 2.0.0
20
- VERSION = '2.10.0'.freeze
20
+ VERSION = '2.10.1'.freeze
21
21
  end
@@ -94,7 +94,7 @@ describe 'Change stream integration', retry: 4 do
94
94
  it 'watch raises error' do
95
95
  expect do
96
96
  authorized_collection.watch
97
- end.to raise_error(Mongo::Error::OperationFailure, "Failing command due to 'failCommand' failpoint (100)")
97
+ end.to raise_error(Mongo::Error::OperationFailure, /Failing command due to 'failCommand' failpoint \(100\)/)
98
98
  end
99
99
  end
100
100
 
@@ -243,7 +243,7 @@ describe 'Change stream integration', retry: 4 do
243
243
 
244
244
  expect do
245
245
  enum.next
246
- end.to raise_error(Mongo::Error::OperationFailure, "Failing command due to 'failCommand' failpoint (101)")
246
+ end.to raise_error(Mongo::Error::OperationFailure, /Failing command due to 'failCommand' failpoint \(101\)/)
247
247
  end
248
248
  end
249
249
  end
@@ -354,7 +354,7 @@ describe 'Change stream integration', retry: 4 do
354
354
 
355
355
  expect do
356
356
  enum.try_next
357
- end.to raise_error(Mongo::Error::OperationFailure, "Failing command due to 'failCommand' failpoint (101)")
357
+ end.to raise_error(Mongo::Error::OperationFailure, /Failing command due to 'failCommand' failpoint \(101\)/)
358
358
  end
359
359
  end
360
360
 
@@ -377,7 +377,7 @@ describe 'Change stream integration', retry: 4 do
377
377
 
378
378
  expect do
379
379
  enum.try_next
380
- end.to raise_error(Mongo::Error::OperationFailure, "Failing command due to 'failCommand' failpoint (101)")
380
+ end.to raise_error(Mongo::Error::OperationFailure, /Failing command due to 'failCommand' failpoint \(101\)/)
381
381
  end
382
382
  end
383
383
  end
@@ -107,7 +107,7 @@ describe 'Command monitoring' do
107
107
  subscriber.clear_events!
108
108
  expect do
109
109
  command.execute(server)
110
- end.to raise_error(Mongo::Error::OperationFailure, 'Not enough data-bearing nodes (100)')
110
+ end.to raise_error(Mongo::Error::OperationFailure, /Not enough data-bearing nodes \(100\)/)
111
111
 
112
112
  expect(subscriber.started_events.length).to eq(1)
113
113
  event = subscriber.started_events.first
@@ -409,7 +409,7 @@ describe 'Read preference' do
409
409
  res = collection.find({}, {session: session}.merge(find_options || {})).to_a.count
410
410
  expect(res).to eq(1)
411
411
  end
412
- end.to raise_error(Mongo::Error::InvalidTransactionOperation, "read preference in a transaction must be primary (requested: secondary)")
412
+ end.to raise_error(Mongo::Error::InvalidTransactionOperation, /read preference in a transaction must be primary \(requested: secondary\)/)
413
413
  end
414
414
  end
415
415
 
@@ -478,7 +478,7 @@ describe 'Read preference' do
478
478
  res = collection.find({}, {session: session}.merge(find_options || {})).to_a.count
479
479
  expect(res).to eq(1)
480
480
  end
481
- end.to raise_error(Mongo::Error::InvalidTransactionOperation, "read preference in a transaction must be primary (requested: secondary)")
481
+ end.to raise_error(Mongo::Error::InvalidTransactionOperation, /read preference in a transaction must be primary \(requested: secondary\)/)
482
482
  end
483
483
  end
484
484
  end
@@ -107,6 +107,18 @@ describe 'Retryable writes integration tests' do
107
107
  }.to raise_error(Mongo::Error::OperationFailure, /other error/)
108
108
  expect(expectation).to eq(unsuccessful_retry_value)
109
109
  end
110
+
111
+ it 'indicates server used for operation' do
112
+ expect {
113
+ operation
114
+ }.to raise_error(Mongo::Error::OperationFailure, /on #{ClusterConfig.instance.primary_address_str}/)
115
+ end
116
+
117
+ it 'indicates first attempt' do
118
+ expect {
119
+ operation
120
+ }.to raise_error(Mongo::Error::OperationFailure, /attempt 1/)
121
+ end
110
122
  end
111
123
  end
112
124
  end
@@ -169,16 +181,17 @@ describe 'Retryable writes integration tests' do
169
181
  end
170
182
 
171
183
  [
172
- Mongo::Error::SocketError,
173
- Mongo::Error::SocketTimeoutError,
174
- Mongo::Error::OperationFailure.new('not master'),
175
- Mongo::Error::OperationFailure.new('node is recovering'),
176
- ].each do |retryable_error|
184
+ [Mongo::Error::SocketError],
185
+ [Mongo::Error::SocketTimeoutError],
186
+ [Mongo::Error::OperationFailure, 'not master'],
187
+ [Mongo::Error::OperationFailure, 'node is recovering'],
188
+ ].each do |error_cls, error_msg|
189
+ # Note: actual exception instances must be different between tests
177
190
 
178
- context "when the first error is a #{retryable_error}" do
191
+ context "when the first error is a #{error_cls}/#{error_msg}" do
179
192
 
180
193
  let(:error) do
181
- retryable_error
194
+ error_cls.new(error_msg)
182
195
  end
183
196
 
184
197
  before do
@@ -197,12 +210,24 @@ describe 'Retryable writes integration tests' do
197
210
  Mongo::Error::SocketError
198
211
  end
199
212
 
200
- it 'does not retry writes and raises the second error' do
213
+ it 'raises the second error' do
201
214
  expect {
202
215
  operation
203
216
  }.to raise_error(second_error)
204
217
  expect(expectation).to eq(unsuccessful_retry_value)
205
218
  end
219
+
220
+ it 'indicates server used for operation' do
221
+ expect {
222
+ operation
223
+ }.to raise_error(Mongo::Error, /on #{ClusterConfig.instance.primary_address_str}/)
224
+ end
225
+
226
+ it 'indicates second attempt' do
227
+ expect {
228
+ operation
229
+ }.to raise_error(Mongo::Error, /attempt 2/)
230
+ end
206
231
  end
207
232
 
208
233
  context 'when the second error is a SocketTimeoutError' do
@@ -211,7 +236,7 @@ describe 'Retryable writes integration tests' do
211
236
  Mongo::Error::SocketTimeoutError
212
237
  end
213
238
 
214
- it 'does not retry writes and raises the second error' do
239
+ it 'raises the second error' do
215
240
  expect {
216
241
  operation
217
242
  }.to raise_error(second_error)
@@ -225,7 +250,7 @@ describe 'Retryable writes integration tests' do
225
250
  Mongo::Error::OperationFailure.new('not master')
226
251
  end
227
252
 
228
- it 'does not retry writes and raises the second error' do
253
+ it 'raises the second error' do
229
254
  expect {
230
255
  operation
231
256
  }.to raise_error(second_error)
@@ -253,12 +278,30 @@ describe 'Retryable writes integration tests' do
253
278
  StandardError
254
279
  end
255
280
 
256
- it 'does not retry writes and raises the first error' do
281
+ it 'raises the first error' do
257
282
  expect {
258
283
  operation
259
284
  }.to raise_error(error)
260
285
  expect(expectation).to eq(unsuccessful_retry_value)
261
286
  end
287
+
288
+ it 'indicates server used for operation' do
289
+ expect {
290
+ operation
291
+ }.to raise_error(Mongo::Error, /on #{ClusterConfig.instance.primary_address_str}/)
292
+ end
293
+
294
+ it 'indicates first attempt' do
295
+ expect {
296
+ operation
297
+ }.to raise_error(Mongo::Error, /attempt 1/)
298
+ end
299
+
300
+ it 'indicates retry was performed' do
301
+ expect {
302
+ operation
303
+ }.to raise_error(Mongo::Error, /later retry failed: StandardError/)
304
+ end
262
305
  end
263
306
  end
264
307
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.10.0
4
+ version: 2.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Brock
@@ -31,7 +31,7 @@ cert_chain:
31
31
  bMYVwXXhV8czdzgkQB/ZPWHSbEWXnmkze1mzvqWBCPOVXYrcnL9cnEl/RoxtS1hr
32
32
  Db6Ac6mCUSYfYHBWpWqxjc45n70i5Xi1
33
33
  -----END CERTIFICATE-----
34
- date: 2019-08-13 00:00:00.000000000 Z
34
+ date: 2019-08-29 00:00:00.000000000 Z
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: bson
@@ -140,6 +140,7 @@ files:
140
140
  - lib/mongo/database/view.rb
141
141
  - lib/mongo/dbref.rb
142
142
  - lib/mongo/error.rb
143
+ - lib/mongo/error/auth_error.rb
143
144
  - lib/mongo/error/bulk_write_error.rb
144
145
  - lib/mongo/error/change_stream_resumable.rb
145
146
  - lib/mongo/error/closed_stream.rb
@@ -180,6 +181,7 @@ files:
180
181
  - lib/mongo/error/need_primary_server.rb
181
182
  - lib/mongo/error/no_server_available.rb
182
183
  - lib/mongo/error/no_srv_records.rb
184
+ - lib/mongo/error/notable.rb
183
185
  - lib/mongo/error/operation_failure.rb
184
186
  - lib/mongo/error/parser.rb
185
187
  - lib/mongo/error/pool_closed_error.rb
@@ -355,11 +357,11 @@ files:
355
357
  - lib/mongo/operation/shared/polymorphic_lookup.rb
356
358
  - lib/mongo/operation/shared/polymorphic_result.rb
357
359
  - lib/mongo/operation/shared/read_preference_supported.rb
360
+ - lib/mongo/operation/shared/response_handling.rb
358
361
  - lib/mongo/operation/shared/result/aggregatable.rb
359
362
  - lib/mongo/operation/shared/result/use_legacy_error_parser.rb
360
363
  - lib/mongo/operation/shared/sessions_supported.rb
361
364
  - lib/mongo/operation/shared/specifiable.rb
362
- - lib/mongo/operation/shared/unpinnable.rb
363
365
  - lib/mongo/operation/shared/write.rb
364
366
  - lib/mongo/operation/shared/write_concern_supported.rb
365
367
  - lib/mongo/operation/update.rb
metadata.gz.sig CHANGED
Binary file
@@ -1,39 +0,0 @@
1
- # Copyright (C) 2014-2019 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
- module Mongo
16
- module Operation
17
- module Unpinnable
18
-
19
- private
20
-
21
- # Unpins the session if the session is pinned and the yielded to block
22
- # raises errors that are required to unpin the session.
23
- #
24
- # @note This method takes the session as an argument because Unpinnable
25
- # is included in BulkWrite which does not store the session in the
26
- # receiver (despite Specifiable doing so).
27
- #
28
- # @param [ Session | nil ] Session to consider.
29
- def unpin_maybe(session)
30
- yield
31
- rescue Mongo::Error => e
32
- if session
33
- session.unpin_maybe(e)
34
- end
35
- raise
36
- end
37
- end
38
- end
39
- end