RUBY-297 when possible, include error codes and

return objects in exception classes.
This commit is contained in:
Kyle Banker 2011-09-06 14:22:50 -04:00
parent 1e951d6734
commit 046038e18d
5 changed files with 38 additions and 9 deletions

View File

@ -448,7 +448,7 @@ module Mongo
if num_received == 1 && (error = docs[0]['err'] || docs[0]['errmsg'])
close if error == "not master"
error = "wtimeout" if error == "timeout"
raise Mongo::OperationFailure, docs[0]['code'].to_s + ': ' + error
raise OperationFailure.new(docs[0]['code'].to_s + ': ' + error, docs[0]['code'], docs[0])
end
docs[0]

View File

@ -122,10 +122,10 @@ module Mongo
# connection. The next request will re-open on master server.
if err == "not master"
@connection.close
raise ConnectionFailure, err
raise ConnectionFailure.new(err, doc['code'], doc)
end
raise OperationFailure, err
raise OperationFailure.new(err, doc['code'], doc)
end
if @transformer.nil?
@ -175,7 +175,7 @@ module Mongo
response = @db.command(command)
return response['n'].to_i if Mongo::Support.ok?(response)
return 0 if response['errmsg'] == "ns missing"
raise OperationFailure, "Count failed: #{response['errmsg']}"
raise OperationFailure.new("Count failed: #{response['errmsg']}", response['code'], response)
end
# Sort this cursor's results.

View File

@ -123,13 +123,14 @@ module Mongo
auth['user'] = username
auth['nonce'] = nonce
auth['key'] = Mongo::Support.auth_key(username, password, nonce)
if ok?(self.command(auth, :check_response => false, :socket => opts[:socket]))
if ok?(doc = self.command(auth, :check_response => false, :socket => opts[:socket]))
if save_auth
@connection.add_auth(@name, username, password)
end
true
else
raise(Mongo::AuthenticationError, "Failed to authenticate user '#{username}' on db '#{self.name}'")
message = "Failed to authenticate user '#{username}' on db '#{self.name}'"
raise Mongo::AuthenticationError.new(message, doc['code'], doc)
end
end
@ -506,7 +507,13 @@ module Mongo
if result.nil?
raise OperationFailure, "Database command '#{selector.keys.first}' failed: returned null."
elsif (check_response && !ok?(result))
raise OperationFailure, "Database command '#{selector.keys.first}' failed: #{result.inspect}"
message = "Database command '#{selector.keys.first}' failed: ("
message << result.map do |key, value|
"#{key}: '#{value}'"
end.join('; ')
message << ').'
code = result['code'] || result['assertionCode']
raise OperationFailure.new(message, code, result)
else
result
end

View File

@ -22,7 +22,20 @@ module Mongo
class MongoRubyError < StandardError; end
# Raised when MongoDB itself has returned an error.
class MongoDBError < RuntimeError; end
class MongoDBError < RuntimeError
# @return The entire failed command's response object, if available.
attr_reader :result
# @return The failed command's error code, if availab.e
attr_reader :error_code
def initialize(message=nil, error_code=nil, result=nil)
@error_code = error_code
@result = result
super(message)
end
end
# Raised when configuration options cause connections, queries, etc., to fail.
class ConfigurationError < MongoRubyError; end

View File

@ -206,8 +206,17 @@ class DBTest < Test::Unit::TestCase
def test_check_command_response
command = {:forceerror => 1}
assert_raise OperationFailure do
raised = false
begin
@@db.command(command)
rescue => ex
raised = true
assert ex.message.include?("forced error"),
"error message does not contain 'forced error'"
assert_equal 10038, ex.error_code
assert_equal 10038, ex.result['assertionCode']
ensure
assert raised, "No assertion raised!"
end
end