Skip to content

Commit 64780ee

Browse files
committed
feat(MongoMemoryReplSet): change more errors to "StateError" & more consistent logs
- change more errors to "StateError" - more consistent logs - more comments - better variable names - small consistency changes
1 parent b6f3a5e commit 64780ee

File tree

3 files changed

+51
-32
lines changed

3 files changed

+51
-32
lines changed

packages/mongodb-memory-server-core/src/MongoMemoryReplSet.ts

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { EventEmitter } from 'events';
2-
import MongoMemoryServer, { AutomaticAuth } from './MongoMemoryServer';
3-
import { MongoMemoryServerOpts } from './MongoMemoryServer';
2+
import { MongoMemoryServer, AutomaticAuth, MongoMemoryServerOpts } from './MongoMemoryServer';
43
import {
54
assertion,
65
authDefault,
@@ -206,10 +205,7 @@ export class MongoMemoryReplSet extends EventEmitter {
206205
}
207206

208207
set binaryOpts(val: MongoBinaryOpts) {
209-
assertion(
210-
this._state === MongoMemoryReplSetStates.stopped,
211-
new StateError([MongoMemoryReplSetStates.stopped], this._state)
212-
);
208+
assertionIsMMSRSState(MongoMemoryReplSetStates.stopped, this._state);
213209
this._binaryOpts = val;
214210
}
215211

@@ -275,7 +271,7 @@ export class MongoMemoryReplSet extends EventEmitter {
275271
opts.storageEngine = baseOpts.storageEngine;
276272
}
277273

278-
log(' instance opts:', opts);
274+
log('getInstanceOpts: instance opts:', opts);
279275

280276
return opts;
281277
}
@@ -287,18 +283,22 @@ export class MongoMemoryReplSet extends EventEmitter {
287283
* @throws if an server doesnt have "instanceInfo.port" defined
288284
*/
289285
getUri(otherDb?: string | boolean): string {
290-
log('getUri:', this._state);
291-
switch (this._state) {
286+
log('getUri:', this.state);
287+
switch (this.state) {
292288
case MongoMemoryReplSetStates.running:
293289
case MongoMemoryReplSetStates.init:
294290
break;
295291
case MongoMemoryReplSetStates.stopped:
296292
default:
297-
throw new Error('Replica Set is not running. Use debug for more info.');
293+
throw new StateError(
294+
[MongoMemoryReplSetStates.running, MongoMemoryReplSetStates.init],
295+
this.state
296+
);
298297
}
299298

300299
let dbName = this._replSetOpts.dbName;
301300

301+
// double instead of isNullOrUndefined to respect type "boolean" being "false"
302302
if (!!otherDb) {
303303
dbName = typeof otherDb === 'string' ? otherDb : generateDbName();
304304
}
@@ -320,13 +320,13 @@ export class MongoMemoryReplSet extends EventEmitter {
320320
* @throws if state is already "running"
321321
*/
322322
async start(): Promise<void> {
323-
log('start');
324-
switch (this._state) {
323+
log('start:', this.state);
324+
switch (this.state) {
325325
case MongoMemoryReplSetStates.stopped:
326326
break;
327327
case MongoMemoryReplSetStates.running:
328328
default:
329-
throw new Error('Already in "init" or "running" state. Use debug for more info.');
329+
throw new StateError([MongoMemoryReplSetStates.stopped], this.state);
330330
}
331331
this.stateChange(MongoMemoryReplSetStates.init); // this needs to be executed before "setImmediate"
332332
await ensureAsync();
@@ -360,12 +360,21 @@ export class MongoMemoryReplSet extends EventEmitter {
360360
// Any servers defined within `_instanceOpts` should be started first as
361361
// the user could have specified a `dbPath` in which case we would want to perform
362362
// the `replSetInitiate` command against that server.
363-
this._instanceOpts.forEach((opts) => {
364-
log(` starting server from instanceOpts (count: ${this.servers.length + 1}):`, opts);
363+
this._instanceOpts.forEach((opts, index) => {
364+
log(
365+
`initAllServers: starting special server "${index + 1}" of "${
366+
this._instanceOpts.length
367+
}" from instanceOpts (count: ${this.servers.length + 1}):`,
368+
opts
369+
);
365370
this.servers.push(this._initServer(this.getInstanceOpts(opts)));
366371
});
367372
while (this.servers.length < this._replSetOpts.count) {
368-
log(` starting server ${this.servers.length + 1} of ${this._replSetOpts.count}`);
373+
log(
374+
`initAllServers: starting extra server "${this.servers.length + 1}" of "${
375+
this._replSetOpts.count
376+
}" (count: ${this.servers.length + 1})`
377+
);
369378
this.servers.push(this._initServer(this.getInstanceOpts()));
370379
}
371380

@@ -392,7 +401,7 @@ export class MongoMemoryReplSet extends EventEmitter {
392401
return true;
393402
})
394403
.catch((err) => {
395-
log(err);
404+
log('stop:', err);
396405
this.stateChange(MongoMemoryReplSetStates.stopped, err);
397406

398407
return false;
@@ -459,9 +468,9 @@ export class MongoMemoryReplSet extends EventEmitter {
459468
return;
460469
case MongoMemoryReplSetStates.stopped:
461470
default:
462-
// throw an error if not "running" or "init"
463-
throw new Error(
464-
'State is not "running" or "init" - cannot wait on something that dosnt start'
471+
throw new StateError(
472+
[MongoMemoryReplSetStates.running, MongoMemoryReplSetStates.init],
473+
this.state
465474
);
466475
}
467476
}
@@ -485,10 +494,11 @@ export class MongoMemoryReplSet extends EventEmitter {
485494
});
486495
log('_initReplSet: connected');
487496

497+
// try-finally to close connection in any case
488498
try {
489499
let adminDb = con.db('admin');
490500

491-
const members = uris.map((uri, idx) => ({ _id: idx, host: getHost(uri) }));
501+
const members = uris.map((uri, index) => ({ _id: index, host: getHost(uri) }));
492502
const rsConfig = {
493503
_id: this._replSetOpts.name,
494504
members,
@@ -497,6 +507,7 @@ export class MongoMemoryReplSet extends EventEmitter {
497507
...this._replSetOpts.configSettings,
498508
},
499509
};
510+
// try-catch because the first "command" can fail
500511
try {
501512
log('_initReplSet: trying "replSetInitiate"');
502513
await adminDb.command({ replSetInitiate: rsConfig });
@@ -540,15 +551,15 @@ export class MongoMemoryReplSet extends EventEmitter {
540551
} else {
541552
console.warn(
542553
'Not Restarting ReplSet for Auth\n' +
543-
'Storage engine of current PRIMARY is ephemeralForTest, which does not write data on shutdown, and mongodb does not allow changeing "auth" runtime'
554+
'Storage engine of current PRIMARY is ephemeralForTest, which does not write data on shutdown, and mongodb does not allow changing "auth" runtime'
544555
);
545556
}
546557
}
547558
} catch (e) {
548559
if (e instanceof MongoError && e.errmsg == 'already initialized') {
549-
log(`${e.errmsg}: trying to set old config`);
560+
log(`_initReplSet: "${e.errmsg}": trying to set old config`);
550561
const { config: oldConfig } = await adminDb.command({ replSetGetConfig: 1 });
551-
log('got old config:\n', oldConfig);
562+
log('_initReplSet: got old config:\n', oldConfig);
552563
await adminDb.command({
553564
replSetReconfig: oldConfig,
554565
force: true,
@@ -557,7 +568,7 @@ export class MongoMemoryReplSet extends EventEmitter {
557568
throw e;
558569
}
559570
}
560-
log('_initReplSet: ReplSet-reConfig finished');
571+
log('_initReplSet: ReplSet-reconfig finished');
561572
await this._waitForPrimary();
562573
this.stateChange(MongoMemoryReplSetStates.running);
563574
log('_initReplSet: running');
@@ -591,13 +602,14 @@ export class MongoMemoryReplSet extends EventEmitter {
591602
log('_waitForPrimary: Waiting for an Primary');
592603
let timeoutId: NodeJS.Timeout | undefined;
593604

605+
// "race" because not all servers will be an primary
594606
await Promise.race([
595607
...this.servers.map(
596608
(server) =>
597609
new Promise<void>((res, rej) => {
598610
const instanceInfo = server.instanceInfo;
599611

600-
if (!instanceInfo) {
612+
if (isNullOrUndefined(instanceInfo)) {
601613
return rej(new Error('_waitForPrimary - instanceInfo not present'));
602614
}
603615

@@ -620,7 +632,7 @@ export class MongoMemoryReplSet extends EventEmitter {
620632
clearTimeout(timeoutId);
621633
}
622634

623-
log('_waitForPrimary detected one primary instance ');
635+
log('_waitForPrimary: detected one primary instance ');
624636
}
625637
}
626638

packages/mongodb-memory-server-core/src/__tests__/MongoMemoryReplSet.test.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,8 @@ describe('single server replset', () => {
9393
fail('Expected "waitUntilRunning" to throw');
9494
} catch (err) {
9595
clearTimeout(timeout);
96-
expect(err.message).toEqual(
97-
'State is not "running" or "init" - cannot wait on something that dosnt start'
98-
);
96+
expect(err).toBeInstanceOf(StateError);
97+
expect(err.message).toMatchSnapshot();
9998
}
10099
});
101100

@@ -119,7 +118,8 @@ describe('single server replset', () => {
119118
fail('Expected "getUri" to throw');
120119
} catch (err) {
121120
clearTimeout(timeout);
122-
expect(err.message).toEqual('Replica Set is not running. Use debug for more info.');
121+
expect(err).toBeInstanceOf(StateError);
122+
expect(err.message).toMatchSnapshot();
123123
}
124124
});
125125

@@ -138,7 +138,8 @@ describe('single server replset', () => {
138138
fail('Expected "start" to throw');
139139
} catch (err) {
140140
clearTimeout(timeout);
141-
expect(err.message).toEqual('Already in "init" or "running" state. Use debug for more info.');
141+
expect(err).toBeInstanceOf(StateError);
142+
expect(err.message).toMatchSnapshot();
142143
}
143144
});
144145

packages/mongodb-memory-server-core/src/__tests__/__snapshots__/MongoMemoryReplSet.test.ts.snap

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@ exports[`MongoMemoryReplSet getters & setters state errors setter of "instanceOp
77
exports[`MongoMemoryReplSet getters & setters state errors setter of "replSetOpts" should throw an error if state is not "stopped" 1`] = `"Incorrect State for operation: \\"init\\", allowed States: \\"[stopped]\\""`;
88

99
exports[`single server replset "_initReplSet" should throw an error if _state is not "init" 1`] = `"Incorrect State for operation: \\"running\\", allowed States: \\"[init]\\""`;
10+
11+
exports[`single server replset "getUri" should throw an error if _state is not "running" or "init" 1`] = `"Incorrect State for operation: \\"stopped\\", allowed States: \\"[running,init]\\""`;
12+
13+
exports[`single server replset "start" should throw an error if _state is not "stopped" 1`] = `"Incorrect State for operation: \\"running\\", allowed States: \\"[stopped]\\""`;
14+
15+
exports[`single server replset "waitUntilRunning" should throw an error if _state is not "init" 1`] = `"Incorrect State for operation: \\"stopped\\", allowed States: \\"[running,init]\\""`;

0 commit comments

Comments
 (0)