-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Critical - P2
-
Affects Version/s: 2.21.3
-
Component/s: None
-
None
-
🔵 Done
-
Ruby Drivers
-
Not Needed
-
None
-
None
-
None
-
None
-
None
-
None
Details
The Ruby driver currently does not retry when a SocketError is raised during connection pool check out. This behavior violates the retryable reads specification (see specification), which since 2022-01-25 requires drivers to retry on handshake network failures.
Root Cause Analysis
The issue appears to be in the exception mapping:
- Socket.getaddrinfo raises Ruby's standard SocketError when DNS resolution fails
- The map_exceptions method in Address#socket doesn't map SocketError to Mongo::Error::SocketError
- The retry logic in ReadWorker#modern_read_with_retry only catches Mongo::Error::SocketError and its subclasses
- As a result, the unmapped SocketError bypasses the retry mechanism entirely
Suggested fix
Update the map_exceptions method in Address class to include SocketError in the exception mapping, ensuring it gets converted to Mongo::Error::SocketError so the retry logic can catch and handle it appropriately.
Code References
- Retry logic: https://github.com/mongodb/mongo-ruby-driver/blob/9ce8f9049a069139f2e4ecbaeb4af12c1454fdf1/lib/mongo/retryable/read_worker.rb#L206
- map_exceptions: https://github.com/mongodb/mongo-ruby-driver/blob/9ce8f9049a069139f2e4ecbaeb4af12c1454fdf1/lib/mongo/address.rb#L308
- getaddrinfo call: https://github.com/mongodb/mongo-ruby-driver/blob/9ce8f9049a069139f2e4ecbaeb4af12c1454fdf1/lib/mongo/address.rb#L240