@@ -30,11 +30,25 @@ function executeOperation(topology, operation, callback) {
30
30
throw new TypeError ( 'This method requires a valid operation instance' ) ;
31
31
}
32
32
33
- if ( isUnifiedTopology ( topology ) && topology . shouldCheckForSessionSupport ( ) ) {
34
- return selectServerForSessionSupport ( topology , operation , callback ) ;
33
+ const Promise = topology . s . promiseLibrary ;
34
+
35
+ let result ;
36
+ if ( typeof callback !== 'function' ) {
37
+ result = new Promise ( ( resolve , reject ) => {
38
+ callback = ( err , res ) => {
39
+ if ( err ) return reject ( err ) ;
40
+ resolve ( res ) ;
41
+ } ;
42
+ } ) ;
35
43
}
36
44
37
- const Promise = topology . s . promiseLibrary ;
45
+ if ( isUnifiedTopology ( topology ) && topology . shouldCheckForSessionSupport ( ) ) {
46
+ // Recursive call to executeOperation after a server selection
47
+ // shouldCheckForSessionSupport should return false after a server selection because
48
+ // there will be data bearing servers
49
+ selectServerForSessionSupport ( topology , operation , callback ) ;
50
+ return result ;
51
+ }
38
52
39
53
// The driver sessions spec mandates that we implicitly create sessions for operations
40
54
// that are not explicitly provided with a session.
@@ -45,20 +59,14 @@ function executeOperation(topology, operation, callback) {
45
59
session = topology . startSession ( { owner } ) ;
46
60
operation . session = session ;
47
61
} else if ( operation . session . hasEnded ) {
48
- throw new MongoError ( 'Use of expired sessions is not permitted' ) ;
62
+ callback ( new MongoError ( 'Use of expired sessions is not permitted' ) ) ;
63
+ return result ;
49
64
}
50
- } else if ( operation . session && operation . session . explicit ) {
51
- throw new MongoError ( 'Current topology does not support sessions' ) ;
52
- }
53
-
54
- let result ;
55
- if ( typeof callback !== 'function' ) {
56
- result = new Promise ( ( resolve , reject ) => {
57
- callback = ( err , res ) => {
58
- if ( err ) return reject ( err ) ;
59
- resolve ( res ) ;
60
- } ;
61
- } ) ;
65
+ } else if ( operation . session && ! topology . hasSessionSupport ( ) ) {
66
+ // If the user passed an explicit session and we are still, after server selection,
67
+ // trying to run against a topology that doesn't support sessions we error out.
68
+ callback ( new MongoError ( 'Current topology does not support sessions' ) ) ;
69
+ return result ;
62
70
}
63
71
64
72
function executeCallback ( err , result ) {
@@ -78,15 +86,15 @@ function executeOperation(topology, operation, callback) {
78
86
} else {
79
87
operation . execute ( executeCallback ) ;
80
88
}
81
- } catch ( e ) {
89
+ } catch ( error ) {
82
90
if ( session && session . owner === owner ) {
83
91
session . endSession ( ) ;
84
92
if ( operation . session === session ) {
85
93
operation . clearSession ( ) ;
86
94
}
87
95
}
88
96
89
- throw e ;
97
+ callback ( error ) ;
90
98
}
91
99
92
100
return result ;
@@ -141,11 +149,6 @@ function executeWithServerSelection(topology, operation, callback) {
141
149
callback ( err , null ) ;
142
150
return ;
143
151
}
144
-
145
- if ( serverSelectionOptions . session && topology . hasSessionSupport ( ) ) {
146
- return callback ( new MongoError ( 'Current topology does not support sessions' ) ) ;
147
- }
148
-
149
152
const shouldRetryReads =
150
153
topology . s . options . retryReads !== false &&
151
154
operation . session &&
@@ -165,28 +168,13 @@ function executeWithServerSelection(topology, operation, callback) {
165
168
// TODO: This is only supported for unified topology, it should go away once
166
169
// we remove support for legacy topology types.
167
170
function selectServerForSessionSupport ( topology , operation , callback ) {
168
- const Promise = topology . s . promiseLibrary ;
169
-
170
- let result ;
171
- if ( typeof callback !== 'function' ) {
172
- result = new Promise ( ( resolve , reject ) => {
173
- callback = ( err , result ) => {
174
- if ( err ) return reject ( err ) ;
175
- resolve ( result ) ;
176
- } ;
177
- } ) ;
178
- }
179
-
180
171
topology . selectServer ( ReadPreference . primaryPreferred , err => {
181
172
if ( err ) {
182
- callback ( err ) ;
183
- return ;
173
+ return callback ( err ) ;
184
174
}
185
175
186
176
executeOperation ( topology , operation , callback ) ;
187
177
} ) ;
188
-
189
- return result ;
190
178
}
191
179
192
180
module . exports = executeOperation ;
0 commit comments