Skip to content

Commit a846579

Browse files
fix(shell-api): improve error message on reading from secondary via runCommand MONGOSH-1679 (#1805)
* fix: improve error message on reading from secondary via runCommand * test: add tests * Update packages/shell-api/src/mongo-errors.ts Co-authored-by: Anna Henningsen <[email protected]> * Update packages/shell-api/src/database.ts Co-authored-by: Anna Henningsen <[email protected]> * explicit type * adjust all messages --------- Co-authored-by: Anna Henningsen <[email protected]>
1 parent 968fe96 commit a846579

File tree

4 files changed

+45
-7
lines changed

4 files changed

+45
-7
lines changed

packages/shell-api/src/database.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import {
3131
MongoshUnimplementedError,
3232
} from '@mongosh/errors';
3333
import type { ClientEncryption } from './field-level-encryption';
34+
import type { MongoServerError } from 'mongodb';
35+
3436
chai.use(sinonChai);
3537

3638
describe('Database', function () {
@@ -323,6 +325,21 @@ describe('Database', function () {
323325
}
324326
);
325327
});
328+
329+
it('rephrases the "NotPrimaryNoSecondaryOk" error', async function () {
330+
const originalError: Partial<MongoServerError> = {
331+
message: 'old message',
332+
codeName: 'NotPrimaryNoSecondaryOk',
333+
code: 13435,
334+
};
335+
serviceProvider.runCommandWithCheck.rejects(originalError);
336+
const caughtError = await database
337+
.runCommand({ someCommand: 'someCollection' })
338+
.catch((e) => e);
339+
expect(caughtError.message).to.contain(
340+
'e.g. db.runCommand({ command }, { readPreference: "secondaryPreferred" })'
341+
);
342+
});
326343
});
327344

328345
describe('adminCommand', function () {

packages/shell-api/src/database.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -365,11 +365,19 @@ export default class Database extends ShellApiWithMongoClass {
365365
cmd = { [cmd]: 1 };
366366
}
367367

368-
const hiddenCommands = new RegExp(HIDDEN_COMMANDS);
369-
if (!Object.keys(cmd).some((k) => hiddenCommands.test(k))) {
370-
this._emitDatabaseApiCall('runCommand', { cmd, options });
368+
try {
369+
const hiddenCommands = new RegExp(HIDDEN_COMMANDS);
370+
if (!Object.keys(cmd).some((k) => hiddenCommands.test(k))) {
371+
this._emitDatabaseApiCall('runCommand', { cmd, options });
372+
}
373+
return await this._runCommand(cmd, options);
374+
} catch (error: any) {
375+
if (error.codeName === 'NotPrimaryNoSecondaryOk') {
376+
const message = `not primary - consider passing the readPreference option e.g. db.runCommand({ command }, { readPreference: "secondaryPreferred" })`;
377+
(error as Error).message = message;
378+
}
379+
throw error;
371380
}
372-
return this._runCommand(cmd, options);
373381
}
374382

375383
/**

packages/shell-api/src/mongo-errors.spec.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ describe('mongo-errors', function () {
6161
expect(r.code).to.equal(13435);
6262
expect(r.message).to.contain('setReadPref');
6363
});
64+
65+
it('does not rephrase a NotPrimaryNoSecondaryOk error with db.runCommand example', function () {
66+
const e = new MongoError(
67+
'not primary - consider passing the readPreference option e.g. db.runCommand({ command }, { readPreference: "secondaryPreferred" })'
68+
);
69+
e.code = 13435;
70+
const r = rephraseMongoError(e);
71+
expect(r).to.equal(e);
72+
expect(r.code).to.equal(13435);
73+
expect(r.message).not.to.contain('setReadPref');
74+
});
6475
});
6576
});
6677

@@ -101,7 +112,7 @@ describe('mongo-errors', function () {
101112
expect.fail('expected error');
102113
} catch (e: any) {
103114
expect(e).to.equal(error);
104-
expect(e.message).to.contain('not primary and secondaryOk=false');
115+
expect(e.message).to.contain('not primary');
105116
expect(e.message).to.contain('db.getMongo().setReadPref()');
106117
expect(e.message).to.contain('readPreference');
107118
}

packages/shell-api/src/mongo-errors.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ const ERROR_REPHRASES: MongoErrorRephrase[] = [
99
{
1010
// NotPrimaryNoSecondaryOk (also used for old terminology)
1111
code: 13435,
12-
replacement:
13-
'not primary and secondaryOk=false - consider using db.getMongo().setReadPref() or readPreference in the connection string',
12+
replacement: (message) =>
13+
message.includes('db.runCommand')
14+
? message
15+
: 'not primary - consider using db.getMongo().setReadPref() or readPreference in the connection string',
1416
},
1517
];
1618

0 commit comments

Comments
 (0)