Skip to content

Commit 079bd6c

Browse files
authored
fix(NODE-3305): beforeHandshake flag is always true (#2854)
1 parent 51e9768 commit 079bd6c

File tree

4 files changed

+74
-3
lines changed

4 files changed

+74
-3
lines changed

src/cmap/connection.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
281281
if (issue.isTimeout) {
282282
op.cb(
283283
new MongoNetworkTimeoutError(`connection ${this.id} to ${this.address} timed out`, {
284-
beforeHandshake: !!this[kIsMaster]
284+
beforeHandshake: this.ismaster == null
285285
})
286286
);
287287
} else if (issue.isClose) {

src/error.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,8 @@ export class MongoNetworkError extends MongoError {
189189
super(message);
190190
this.name = 'MongoNetworkError';
191191

192-
if (options && options.beforeHandshake === true) {
193-
this[kBeforeHandshake] = true;
192+
if (options && typeof options.beforeHandshake === 'boolean') {
193+
this[kBeforeHandshake] = options.beforeHandshake;
194194
}
195195
}
196196
}

test/unit/cmap/connection.test.js

+48
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const { connect } = require('../../../src/cmap/connect');
55
const { Connection } = require('../../../src/cmap/connection');
66
const { expect } = require('chai');
77
const { ns } = require('../../../src/utils');
8+
const { getSymbolFrom } = require('../../tools/utils');
89

910
describe('Connection - unit/cmap', function () {
1011
let server;
@@ -58,4 +59,51 @@ describe('Connection - unit/cmap', function () {
5859
});
5960
});
6061
});
62+
63+
it('should throw a network error with kBeforeHandshake set to false on timeout after hand shake', function (done) {
64+
server.setMessageHandler(request => {
65+
const doc = request.document;
66+
if (doc.ismaster || doc.hello) {
67+
request.reply(mock.DEFAULT_ISMASTER_36);
68+
}
69+
// respond to no other requests to trigger timeout event
70+
});
71+
72+
const options = {
73+
hostAddress: server.hostAddress()
74+
};
75+
76+
connect(options, (err, conn) => {
77+
expect(err).to.be.a('undefined');
78+
expect(conn).to.be.instanceOf(Connection);
79+
expect(conn).to.have.property('ismaster').that.is.a('object');
80+
81+
conn.command(ns('$admin.cmd'), { ping: 1 }, { socketTimeoutMS: 50 }, err => {
82+
const beforeHandshakeSymbol = getSymbolFrom(err, 'beforeHandshake', false);
83+
expect(beforeHandshakeSymbol).to.be.a('symbol');
84+
expect(err).to.have.property(beforeHandshakeSymbol, false);
85+
86+
done();
87+
});
88+
});
89+
});
90+
91+
it('should throw a network error with kBeforeHandshake set to true on timeout before hand shake', function (done) {
92+
// respond to no requests to trigger timeout event
93+
server.setMessageHandler(() => {});
94+
95+
const options = {
96+
hostAddress: server.hostAddress(),
97+
socketTimeoutMS: 50
98+
};
99+
100+
connect(options, (err, conn) => {
101+
expect(conn).to.be.a('undefined');
102+
103+
const beforeHandshakeSymbol = getSymbolFrom(err, 'beforeHandshake');
104+
expect(err).to.have.property(beforeHandshakeSymbol, true);
105+
106+
done();
107+
});
108+
});
61109
});

test/unit/errors.test.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use strict';
2+
3+
const expect = require('chai').expect;
4+
const { getSymbolFrom } = require('../tools/utils');
5+
const MongoNetworkError = require('../../src/error').MongoNetworkError;
6+
7+
describe('MongoErrors', function () {
8+
describe('MongoNetworkError', function () {
9+
it('should only define beforeHandshake symbol if boolean option passed in', function () {
10+
const errorWithOptionTrue = new MongoNetworkError('', { beforeHandshake: true });
11+
expect(getSymbolFrom(errorWithOptionTrue, 'beforeHandshake', false)).to.be.a('symbol');
12+
13+
const errorWithOptionFalse = new MongoNetworkError('', { beforeHandshake: false });
14+
expect(getSymbolFrom(errorWithOptionFalse, 'beforeHandshake', false)).to.be.a('symbol');
15+
16+
const errorWithBadOption = new MongoNetworkError('', { beforeHandshake: 'not boolean' });
17+
expect(getSymbolFrom(errorWithBadOption, 'beforeHandshake', false)).to.be.an('undefined');
18+
19+
const errorWithoutOption = new MongoNetworkError('');
20+
expect(getSymbolFrom(errorWithoutOption, 'beforeHandshake', false)).to.be.an('undefined');
21+
});
22+
});
23+
});

0 commit comments

Comments
 (0)