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 140

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 62

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 66

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 47

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 70

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 51

attr_reader :message

#repliesArray<Protocol::Message> (readonly)

Returns:

Since:

  • 2.0.0

[ GitHub ]

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

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 55

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 102

def write_concern_error?
  !!write_concern_error_document
end

#wtimeout (readonly)

Since:

  • 2.0.0

[ GitHub ]

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

attr_reader :wtimeout

Instance Method Details

#append(message, error) (private)

Since:

  • 2.0.0

[ GitHub ]

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

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 158

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')
  parse_single(@message, 'errmsg', write_concern_error_document) if write_concern_error_document
  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 211

def parse_code
  if document['ok'] == 1
    @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? && (subdoc = write_concern_error_document)
    @code = subdoc['code']
    @code_name = subdoc['codeName']
  end

  return unless @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
  return unless write_errors = document['writeErrors']

  codes = write_errors.map { |e| e['code'] }.compact
  return unless 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

#parse_flag(message) (private)

Since:

  • 2.0.0

[ GitHub ]

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

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 241

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

#parse_multiple(message, key) (private)

Since:

  • 2.0.0

[ GitHub ]

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

def parse_multiple(message, key)
  return unless errors = document[key]

  errors.each do |error|
    parse_single(message, 'errmsg', error)
  end
end

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

Since:

  • 2.0.0

[ GitHub ]

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

def parse_single(message, key, doc = document)
  return unless error = doc[key]

  append(message, error)
end

#parse_wtimeout (private)

Since:

  • 2.0.0

[ GitHub ]

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

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 120

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 129

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 111

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 135

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