[SERVER-2635] findAndModify() and getLastError() Problem Created: 28/Feb/11  Updated: 17/Mar/11  Resolved: 28/Feb/11

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: 1.6.5
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Tom Wardrop Assignee: Unassigned
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Mac OS X 10.6.6; MongoDB 1.6.5


Backwards Compatibility: Fully Compatible
Operating System: ALL
Participants:

 Description   

When using the "findAndModify" command, "getLastError" only returns the result of the last of the two operations. By default, this means it returns the result of the "update" operation (which is normally desirable), but when one uses the "new" option, getLastError returns the result of the "find" operation, so any error in the update clause is inaccessible.

The following sequence of commands demonstrates the problem:
db.test.insert(

{name: 'bob'}

)
db.test.findAndModify({query:

{name: 'bob'}

, update: {$set:

{age: 30}

, $inc: {age: 3}}, new: true})
db.getLastError()

Ideally, what you should receive when you run the last line, db.getLastError(), you should get an error "Field name duplication not allowed with modifiers". Instead, you get null, as the find operation (the 2nd of the two internal operations), succeeded. If you had the "new" option set to false, and you had a similar error in the find/query portion of the command, you'd get the same problem.



 Comments   
Comment by Tom Wardrop [ 01/Mar/11 ]

I just tried 1.8.0-rc0 and nothing seems to be any different. findAndModify seems to behave exactly the same. Eliot, have you tried the two commands I posted earlier? Try running them in 1.8, and tell me exactly what you get. I get...

{
"value" :

{ "_id" : ObjectId("4d6cbd941ee2917751580cab"), "name" : "bob" }

,
"ok" : 1
}

Which is obviously not what I would have expected. I'm expecting to see an error regarding the conflict in the update clause.

EDIT: Whoops, I wasn't actually running 1.8.0-rc0. I used version() and it reported 1.8.0-rc0, but I now found out that version() returns the client version, and db.version() returns the server version. A little confusing, but I hopefully won't make that mistake again. Indeed, 1.8.0-rc0 does seem to have the fix you mention. Thanks.

Comment by Tom Wardrop [ 28/Feb/11 ]

Ah ha, now that's the answer I was after I'll have to hang out for 1.8 then. Thanks.

Comment by Eliot Horowitz (Inactive) [ 28/Feb/11 ]

That's a bug with the findAndModify command itself, which was fixed in 1.7 and works as expected in 1.8.0-rc0

Comment by Tom Wardrop [ 28/Feb/11 ]

Hi Eliot,

I don't believe the problem is resolved. Sure, as you say, this may be by design, but that still doesn't answer the question: How do I get error messages from findAndModify? How do I know whether the update portion of the command as succeeded or not?

Going off what you said, running the following should give me an error in the return value:

db.test.insert(

{name: 'bob'}

)
db.runCommand({findAndModify: 'test', query:

{name: 'bob'}

, update: {$set:

{age: 30}

, $inc: {age: 3}}, new: true})

The update fails, but I'm told nothing of it. Ironically however, if the find operation fails (i.e. doesn't find a match), then an error is returned "No matching object found". So the problem is, how do I know whether the update in a findAndModify operation has succeeded or not?

Comment by Eliot Horowitz (Inactive) [ 28/Feb/11 ]

findAndModify is a command, meaning the error is returned in the result.

Generated at Thu Feb 08 03:00:44 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.