123456789_123456789_123456789_123456789_123456789_

Class: Mongo::Error::Parser Private

Do not use. This class is for internal use only.
Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
Inherits: Object
Defined in: lib/mongo/error/parser.rb

Overview

Class for parsing the various forms that errors can come in from MongoDB command responses.

The errors can be reported by the server in a number of ways:

  • ok:0 response indicates failure. In newer servers, code, codeName and errmsg fields should be set. In older servers some may not be set.

  • ok:1 response with a write concern error (writeConcernError top-level field). This indicates that the node responding successfully executed the request, but not enough other nodes successfully executed the request to satisfy the write concern.

  • ok:1 response with writeErrors top-level field. This can be obtained in a bulk write but also in a non-bulk write. In a non-bulk write there should be exactly one error in the writeErrors list. The case of multiple errors is handled by BulkWrite::Result.

  • ok:1 response with writeConcernErrors top-level field. This can only be obtained in a bulk write and is handled by BulkWrite::Result, not by this class.

Note that writeErrors do not have codeName fields - they just provide codes and messages. writeConcernErrors may similarly not provide code names.

Since:

  • 2.0.0

Constant Summary

SdamErrorDetection - Included

NODE_RECOVERING_CODES, NODE_SHUTTING_DOWN_CODES, NOT_MASTER_CODES

Class Method Summary

Instance Attribute Summary

SdamErrorDetection - Included

#node_recovering?

Whether the error is a “node is recovering” error, or one of its variants.

#node_shutting_down?

Whether the error is a “node is shutting down” type error.

#not_master?

Whether the error is a “not master” error, or one of its variants.

Instance Method Summary

Class Method Details

.build_message(code: nil, code_name: nil, message: nil)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 177

def build_message(code: nil, code_name: nil, message: nil)
  if code_name && code
    "[#{code}:#{code_name}]: #{message}"
  elsif code_name
    # This surely should never happen, if there's a code name
    # there ought to also be the code provided.
    # Handle this case for completeness.
    "[#{code_name}]: #{message}"
  elsif code
    "[#{code}]: #{message}"
  else
    message
  end
end

Instance Attribute Details

#codeInteger (readonly)

Returns:

  • (Integer)

    The error code parsed from the document.

Since:

  • 2.6.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 88

attr_reader :code

#code_nameString (readonly)

Returns:

  • (String)

    The error code name parsed from the document.

Since:

  • 2.6.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 92

attr_reader :code_name

#documentBSON::Document (readonly)

Returns:

  • (BSON::Document)

    The returned document.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 73

attr_reader :document

#labelsArray<String> (readonly)

Returns:

  • (Array<String>)

    The set of labels associated with the error.

Since:

  • 2.7.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 96

attr_reader :labels

#messageString (readonly)

Returns:

  • (String)

    The full error message to be used in the raised exception.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 77

attr_reader :message

#repliesArray<Protocol::Message> (readonly)

Returns:

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 84

attr_reader :replies

#server_messageString (readonly)

Returns:

  • (String)

    The server-returned error message parsed from the response.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 81

attr_reader :server_message

#write_concern_error?true | false (readonly)

Returns:

  • (true | false)

    Whether the document includes a write concern error. A failure may have a top level error and a write concern error or either one of the two.

Since:

  • 2.10.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 139

def write_concern_error?
  !!write_concern_error_document
end

#wtimeout (readonly)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 99

attr_reader :wtimeout

Instance Method Details

#append(message, error) (private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 242

def append(message, error)
  if message.length > 1
    message.concat(", #{error}")
  else
    message.concat(error)
  end
end

#parse! (private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 195

def parse!
  if document['ok'] != 1 && document['writeErrors']
    raise ArgumentError, "writeErrors should only be given in successful responses"
  end

  @message = +""
  parse_single(@message, '$err')
  parse_single(@message, 'err')
  parse_single(@message, 'errmsg')
  parse_multiple(@message, 'writeErrors')
  if write_concern_error_document
    parse_single(@message, 'errmsg', write_concern_error_document)
  end
  parse_flag(@message)
  parse_code
  parse_labels
  parse_wtimeout

  @server_message = @message
  @message = self.class.build_message(
    code: code,
    code_name: code_name,
    message: @message,
  )
end

#parse_code (private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 250

def parse_code
  if document['ok'] == 1 || @options[:legacy]
    @code = @code_name = nil
  else
    @code = document['code']
    @code_name = document['codeName']
  end

  # Since there is only room for one code, do not replace
  # codes of the top level response with write concern error codes.
  # In practice this should never be an issue as a write concern
  # can only fail after the operation succeeds on the primary.
  if @code.nil? && @code_name.nil?
    if subdoc = write_concern_error_document
      @code = subdoc['code']
      @code_name = subdoc['codeName']
    end
  end

  if @code.nil? && @code_name.nil?
    # If we have writeErrors, and all of their codes are the same,
    # use that code. Otherwise don't set the code
    if write_errors = document['writeErrors']
      codes = write_errors.map { |e| e['code'] }.compact
      if codes.uniq.length == 1
        @code = codes.first
        # code name may not be returned by the server
        @code_name = write_errors.map { |e| e['codeName'] }.compact.first
      end
    end
  end
end

#parse_flag(message) (private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 235

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

#parse_labels (private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 283

def parse_labels
  @labels = document['errorLabels'] || []
end

#parse_multiple(message, key) (private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 227

def parse_multiple(message, key)
  if errors = document[key]
    errors.each do |error|
      parse_single(message, 'errmsg', error)
    end
  end
end

#parse_single(message, key, doc = document) (private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 221

def parse_single(message, key, doc = document)
  if error = doc[key]
    append(message, error)
  end
end

#parse_wtimeout (private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 287

def parse_wtimeout
  @wtimeout = write_concern_error_document &&
    write_concern_error_document['errInfo'] &&
    write_concern_error_document['errInfo']['wtimeout']
end

#write_concern_error_codeInteger | nil

Returns:

  • (Integer | nil)

    The error code for the write concern error, if a write concern error is present and has a code.

Since:

  • 2.10.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 157

def write_concern_error_code
  write_concern_error_document && write_concern_error_document['code']
end

#write_concern_error_code_nameString | nil

Returns:

  • (String | nil)

    The code name for the write concern error, if a write concern error is present and has a code name.

Since:

  • 2.10.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 166

def write_concern_error_code_name
  write_concern_error_document && write_concern_error_document['codeName']
end

#write_concern_error_documentHash | nil

Returns the write concern error document as it was reported by the server, if any.

Returns:

  • (Hash | nil)

    Write concern error as reported to the server.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 148

def write_concern_error_document
  document['writeConcernError']
end

#write_concern_error_labelsArray<String> | nil

write concern error, if there is a write concern error present.

Returns:

  • (Array<String> | nil)

    The error labels associated with this

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/error/parser.rb', line 172

def write_concern_error_labels
  write_concern_error_document && write_concern_error_document['errorLabels']
end