Skip to content

Commit

Permalink
feat: introduce MongoServerSelectionError
Browse files Browse the repository at this point in the history
This error type subclasses the `MongoTimeout` error, but provides
more context that the error was specific to an issue with server
selection.
  • Loading branch information
mbroadst committed Dec 30, 2019
1 parent aee8f57 commit 0cf7ec9
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 7 deletions.
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const connect = require('./lib/mongo_client').connect;
connect.MongoError = core.MongoError;
connect.MongoNetworkError = core.MongoNetworkError;
connect.MongoTimeoutError = core.MongoTimeoutError;
connect.MongoServerSelectionError = core.MongoServerSelectionError;
connect.MongoParseError = core.MongoParseError;
connect.MongoWriteConcernError = core.MongoWriteConcernError;
connect.MongoBulkWriteError = require('./lib/bulk/common').BulkWriteError;
Expand Down
19 changes: 18 additions & 1 deletion lib/core/error.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class MongoParseError extends MongoError {
class MongoTimeoutError extends MongoError {
constructor(message, reason) {
if (reason && reason.error) {
super(reason.error);
super(reason.error.message || reason.error);
} else {
super(message);
}
Expand All @@ -108,6 +108,22 @@ class MongoTimeoutError extends MongoError {
}
}

/**
* An error signifying a client-side server selection error
*
* @param {Error|string|object} message The error message
* @param {string|object} [reason] The reason the timeout occured
* @property {string} message The error message
* @property {string} [reason] An optional reason context for the timeout, generally an error saved during flow of monitoring and selecting servers
* @extends MongoError
*/
class MongoServerSelectionError extends MongoTimeoutError {
constructor(message, reason) {
super(message, reason);
this.name = 'MongoServerSelectionError';
}
}

function makeWriteConcernResultObject(input) {
const output = Object.assign({}, input);

Expand Down Expand Up @@ -246,6 +262,7 @@ module.exports = {
MongoNetworkError,
MongoParseError,
MongoTimeoutError,
MongoServerSelectionError,
MongoWriteConcernError,
mongoErrorContextSymbol,
isRetryableError,
Expand Down
1 change: 1 addition & 0 deletions lib/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module.exports = {
MongoNetworkError: require('./error').MongoNetworkError,
MongoParseError: require('./error').MongoParseError,
MongoTimeoutError: require('./error').MongoTimeoutError,
MongoServerSelectionError: require('./error').MongoServerSelectionError,
MongoWriteConcernError: require('./error').MongoWriteConcernError,
mongoErrorContextSymbol: require('./error').mongoErrorContextSymbol,
// Core
Expand Down
6 changes: 3 additions & 3 deletions lib/core/sdam/server_selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const TopologyType = require('./common').TopologyType;
const ReadPreference = require('../topologies/read_preference');
const MongoError = require('../error').MongoError;
const calculateDurationInMs = require('../utils').calculateDurationInMs;
const MongoTimeoutError = require('../error').MongoTimeoutError;
const MongoServerSelectionError = require('../error').MongoServerSelectionError;

const common = require('./common');
const STATE_CLOSED = common.STATE_CLOSED;
Expand Down Expand Up @@ -260,7 +260,7 @@ function selectServers(topology, selector, timeout, start, callback) {
const duration = calculateDurationInMs(start);
if (duration >= timeout) {
return callback(
new MongoTimeoutError(`Server selection timed out after ${timeout} ms`),
new MongoServerSelectionError(`Server selection timed out after ${timeout} ms`),
topology.description
);
}
Expand Down Expand Up @@ -306,7 +306,7 @@ function selectServers(topology, selector, timeout, start, callback) {
const iterationTimer = setTimeout(() => {
topology.removeListener('topologyDescriptionChanged', descriptionChangedHandler);
callback(
new MongoTimeoutError(
new MongoServerSelectionError(
`Server selection timed out after ${timeout} ms`,
topology.description
)
Expand Down
6 changes: 3 additions & 3 deletions test/unit/sdam/server_selection/spec.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const path = require('path');
const fs = require('fs');
const core = require('../../../../lib/core');
const Topology = core.Topology;
const MongoTimeoutError = core.MongoTimeoutError;
const MongoServerSelectionError = core.MongoServerSelectionError;
const ReadPreference = core.ReadPreference;

// TODO: these should be from `core` when legacy topologies are removed
Expand Down Expand Up @@ -275,7 +275,7 @@ function executeServerSelectionTest(testDefinition, options, testDone) {
}

// default to serverSelectionTimeoutMS of `100` for unit tests
topology.selectServer(selector, { serverSelectionTimeoutMS: 100 }, (err, server) => {
topology.selectServer(selector, { serverSelectionTimeoutMS: 50 }, (err, server) => {
// are we expecting an error?
if (testDefinition.error) {
if (!err) {
Expand All @@ -287,7 +287,7 @@ function executeServerSelectionTest(testDefinition, options, testDone) {

if (err) {
// this is another expected error case
if (expectedServers.length === 0 && err instanceof MongoTimeoutError) return done();
if (expectedServers.length === 0 && err instanceof MongoServerSelectionError) return done();
return done(err);
}

Expand Down

0 comments on commit 0cf7ec9

Please sign in to comment.