It looks like MongoDB changed the format of error objects returned such that the mongo-ruby-driver no longer populates the `error_code` property on exceptions:
Current behavior (with a 2.6 server):
evan@caron:~$ pry [1] pry(main)> gem 'mongo', '~> 1.11' => true [2] pry(main)> require 'mongo' => true [3] pry(main)> conn = Mongo::Connection.new; [4] pry(main)> conn['test']['test_unique'].ensure_index({name: 1}, {unique: true}) => "name_1" [5] pry(main)> conn['test']['test_unique'].save({_id: 1, name: 'evan'}) => 1 [6] pry(main)> conn['test']['test_unique'].save({_id: 2, name: 'evan'}) Mongo::OperationFailure: Database command 'update' failed: (ok: '1'; nModified: '0'; n: '0'; lastOp: 'seconds: 1417480850, increment: 1'; electionId: '547204e1f7f0f1a6e9092731'; writeErrors: '[{"index"=>0, "code"=>11000, "errmsg"=>"insertDocument :: caused by :: 11000 E11000 duplicate key error index: test.test_unique.$name_1 dup key: { : \"evan\" }"}]'). from /home/evan/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/mongo-1.11.1/lib/mongo/db.rb:581:in `command' [7] pry(main)> e = _ex_ => #<Mongo::OperationFailure: Database command 'update' failed: (ok: '1'; nModified: '0'; n: '0'; lastOp: 'seconds: 1417480850, increment: 1'; electionId: '547204e1f7f0f1a6e9092731'; writeErrors: '[{"index"=>0, "code"=>11000, "errmsg"=>"insertDocument :: caused by :: 11000 E11000 duplicate key error index: test.test_unique.$name_1 dup key: { : \"evan\" }"}]').> [8] pry(main)> e.error_code => nil
Previous behavior (with a 2.4 server):
[1] pry(main)> require 'mongo' => true [2] pry(main)> conn = Mongo::Connection.new; [3] pry(main)> conn['test']['test_unique'].ensure_index({name: 1}, {unique: true}) => "name_1" [4] pry(main)> conn['test']['test_unique'].save({_id: 1, name: 'evan'}) => 1 [5] pry(main)> conn['test']['test_unique'].save({_id: 2, name: 'evan'}) Mongo::OperationFailure: 11000: E11000 duplicate key error index: test.test_unique.$name_1 dup key: { : "evan" } from /usr/lib/ruby/gems/1.9.1/gems/mongo-1.10.2/lib/mongo/networking.rb:110:in `send_message_with_gle' [6] pry(main)> e = _ex_ => #<Mongo::OperationFailure: 11000: E11000 duplicate key error index: test.test_unique.$name_1 dup key: { : "evan" }> [7] pry(main)> e.error_code => 11000
I tested this on both 1.8.6 (which we're using in production) and 1.11.1 (the latest release), but haven't tried any other versions. I took a skim through the latest changes on the 1.x-stable branch as well, and none of those seem relevant.