Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/mongo/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ class Error < StandardError
#
# @since 2.0.0
BAD_VALUE = 2.freeze

# Constant for a Cursor not found error.
#
# @since 2.2.3
CURSOR_NOT_FOUND = 'Cursor not found.'
end
end

Expand Down
13 changes: 12 additions & 1 deletion lib/mongo/error/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class Parser
# @return [ String ] message The error message parsed from the document.
attr_reader :message

# @return [ Array<Protocol::Reply> ] replies The message replies.
attr_reader :replies

# Create the new parser with the returned document.
#
# @example Create the new parser.
Expand All @@ -35,8 +38,9 @@ class Parser
# @param [ BSON::Document ] document The returned document.
#
# @since 2.0.0
def initialize(document)
def initialize(document, replies = nil)
@document = document || {}
@replies = replies
parse!
end

Expand All @@ -50,6 +54,7 @@ def parse!
parse_multiple(@message, WRITE_ERRORS)
parse_single(@message, ERRMSG,
document[WRITE_CONCERN_ERROR]) if document[WRITE_CONCERN_ERROR]
parse_flag(@message)
end

def parse_single(message, key, doc = document)
Expand All @@ -66,6 +71,12 @@ def parse_multiple(message, key)
end
end

def parse_flag(message)
if replies && replies.first && replies.first.cursor_not_found?
append(message, CURSOR_NOT_FOUND)
end
end

def append(message, error)
if message.length > 1
message.concat(", #{error}")
Expand Down
4 changes: 2 additions & 2 deletions lib/mongo/operation/result.rb
Original file line number Diff line number Diff line change
Expand Up @@ -290,15 +290,15 @@ def aggregate_written_count
end

def parser
@parser ||= Error::Parser.new(first_document)
@parser ||= Error::Parser.new(first_document, replies)
end

def first_document
@first_document ||= first || BSON::Document.new
end

def query_failure?
replies.first && replies.first.query_failure?
replies.first && (replies.first.query_failure? || replies.first.cursor_not_found?)
end
end
end
Expand Down
12 changes: 12 additions & 0 deletions lib/mongo/protocol/reply.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ def query_failure?
flags.include?(:query_failure)
end

# Determine if the reply had a cursor not found flag.
#
# @example Did the reply have a cursor not found flag.
# reply.cursor_not_found?
#
# @return [ true, false ] If the query cursor was not found.
#
# @since 2.2.3
def cursor_not_found?
flags.include?(:cursor_not_found)
end

# Return the event payload for monitoring.
#
# @example Return the event payload.
Expand Down
15 changes: 15 additions & 0 deletions spec/mongo/operation/result_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,21 @@
expect(result).to_not be_successful
end
end

context 'when the query reply has the cursor_not_found flag set' do

let(:flags) do
[ :cursor_not_found ]
end

let(:documents) do
[]
end

it 'returns false' do
expect(result).to_not be_successful
end
end
end

context 'when the reply is for a write command' do
Expand Down