[SERVER-38993] `mongo --eval` exits with status 0 on failure Created: 14/Jan/19  Updated: 27/Oct/23  Resolved: 14/Jan/19

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

Type: Bug Priority: Minor - P4
Reporter: Oleg Pudeyev (Inactive) Assignee: Kelsey Schubert
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to DOCS-12360 Include mention of exception-handling... Closed
Operating System: ALL
Participants:

 Description   

Trying this on a 4.1 server:

speed% /usr/local/m/versions/4.1/mongo --port 27741 --eval 'db.adminCommand( { setFeatureCompatibilityVersion: "3.4" } )'
MongoDB shell version v4.1.6-84-g00520c2e0b
connecting to: mongodb://127.0.0.1:27741/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("11b04863-67f8-4363-ae0d-a3f343b39712") }
MongoDB server version: 4.1.6-84-g00520c2e0b
{
	"operationTime" : Timestamp(1547495772, 1),
	"ok" : 0,
	"errmsg" : "Invalid command argument. Expected '4.2' or '4.0', found 3.4 in: { setFeatureCompatibilityVersion: \"3.4\", lsid: { id: UUID(\"11b04863-67f8-4363-ae0d-a3f343b39712\") }, $clusterTime: { clusterTime: Timestamp(1547495772, 1), signature: { hash: BinData(0, 0000000000000000000000000000000000000000), keyId: 0 } }, $db: \"admin\" }. See http://dochub.mongodb.org/core/4.0-feature-compatibility.",
	"code" : 2,
	"codeName" : "BadValue",
	"$clusterTime" : {
		"clusterTime" : Timestamp(1547495772, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	}
}
speed% echo $?                                                                                                           
0

As you see, the operation returned

{ok:0}

, but the exit status of the mongo command is 0 indicating success.

Trying a different expression:

speed% /usr/local/m/versions/4.1/mongo --port 27741 --eval 'console.log'                                                  
MongoDB shell version v4.1.6-84-g00520c2e0b
connecting to: mongodb://127.0.0.1:27741/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("ece2b4e4-14ed-4cee-ab59-3a176dc95793") }
MongoDB server version: 4.1.6-84-g00520c2e0b
2019-01-14T14:57:30.050-0500 E QUERY    [js] ReferenceError: console is not defined :
@(shell eval):1:1
2019-01-14T14:57:30.050-0500 E -        [main] exiting with code -4
speed% echo $?
252

And what if I try to execute more than one command?

speed% /usr/local/m/versions/4.1/mongo --port 27741 --eval 'db.adminCommand( { setFeatureCompatibilityVersion: "3.4" } ); print(1)'
MongoDB shell version v4.1.6-84-g00520c2e0b
connecting to: mongodb://127.0.0.1:27741/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("7c6eb26b-19b6-4426-8df6-03d77b97c138") }
MongoDB server version: 4.1.6-84-g00520c2e0b
1

This is interesting. The second command was run but now the output of the first command is not shown. Is the shell recognizing when it is given one command or more than one command and behaving in different ways?

If the shell does specially treat the case of a single-command --eval, when this single command fails, the shell should exit with a non-zero status code.



 Comments   
Comment by Oleg Pudeyev (Inactive) [ 15/Jan/19 ]

OK that is fine, however I thought about what I should search for to figure out how to make mongo exit with an error on failure and couldn't come up with anything, therefore perhaps linking to the doc page mentioned from --help output would be a good idea.

Comment by Kelsey Schubert [ 14/Jan/19 ]

oleg.pudeyev, I don't think that'd be the best place for this content since it could get pretty wordy. I've opened DOCS-12360 to include additional info in our docs. Please feel free to add on if you think I missed something.

Thanks,
Kelsey

Comment by Oleg Pudeyev (Inactive) [ 14/Jan/19 ]

That works well, thank you. Can assert.commandWorked be mentioned somewhere next to --eval option in the help?

Comment by Max Hirschhorn [ 14/Jan/19 ]

As you see, the operation returned {ok:0}, but the exit status of the mongo command is 0 indicating success.

If you'd like the mongo shell to exit with a non-zero return code based on the server's response, then you'll want to assert on the command response using assert.commandWorked() or similar. The ReferenceError from attempting to use console.log was uncaught and is why the mongo shell exited with a non-zero return code.

The second command was run but now the output of the first command is not shown. Is the shell recognizing when it is given one command or more than one command and behaving in different ways?

If the shell does specially treat the case of a single-command --eval, when this single command fails, the shell should exit with a non-zero status code.

The mongo shell has special logic to display the last value that's stored in the magic __lastres__ variable after evaluating an expression. The way JavaScript's evaluation of statements behaves, this corresponds to the result of the last statement in the sequence being printed out.

Comment by Oleg Pudeyev (Inactive) [ 14/Jan/19 ]

Workaround:

speed% /usr/local/m/versions/4.1/mongo --port 27741 --eval 'var result = db.adminCommand( { setFeatureCompatibilityVersion: "4.2" } ); if (!result.ok) { setting_fcv_failed }'

Generated at Thu Feb 08 04:50:41 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.