Skip to content

Commit 39036d7

Browse files
authored
chore(shell-api,java-shell): returnsPromise implies async MONGOSH-655 (#749)
- Make sure that all methods marked with `@returnsPromise` actually return promises - Update the java-shell code to account for that - Remove special handling in the Promise-marking code that was previously necessary as a workaround to get the new async-rewriter going
1 parent a3556dd commit 39036d7

File tree

12 files changed

+41
-31
lines changed

12 files changed

+41
-31
lines changed

packages/java-shell/src/main/kotlin/com/mongodb/mongosh/result/Cursor.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,19 @@ open class Cursor<out T> internal constructor(protected var cursor: Value?, priv
1919
}
2020

2121
override fun hasNext(): Boolean {
22-
val (cursor, _) = checkClosed()
23-
return cursor.invokeMember("hasNext").asBoolean()
22+
val (cursor, converter) = checkClosed()
23+
return converter.unwrapPromise(cursor.invokeMember("hasNext")).asBoolean()
2424
}
2525

2626
override fun next(): T {
2727
val (cursor, converter) = checkClosed()
2828
if (!hasNext()) throw NoSuchElementException()
29-
return converter.toJava(cursor.invokeMember("next")).value as T
29+
return converter.toJava(converter.unwrapPromise(cursor.invokeMember("next"))).value as T
3030
}
3131

3232
fun tryNext(): T {
3333
val (cursor, converter) = checkClosed()
34-
return converter.toJava(cursor.invokeMember("tryNext")).value as T
34+
return converter.toJava(converter.unwrapPromise(cursor.invokeMember("tryNext"))).value as T
3535
}
3636

3737
fun close() {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
org.graalvm.polyglot.PolyglotException: Command failed with error 51024 (Location51024): 'BSON field 'batchSize' value must be >= 0, actual value '-1'' on server %mongohostport%. The full response is {"ok": 0.0, "errmsg": "BSON field 'batchSize' value must be >= 0, actual value '-1'", "code": 51024, "codeName": "Location51024"}
1+
com.mongodb.MongoCommandException: Command failed with error 51024 (Location51024): 'BSON field 'batchSize' value must be >= 0, actual value '-1'' on server %mongohostport%. The full response is {"ok": 0.0, "errmsg": "BSON field 'batchSize]' value must be >= 0, actual value '-1'", "code": 51024, "codeName": "Location51024"}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
com.mongodb.MongoCommandException: Command failed with error 51024 (Location51024): 'BSON field 'batchSize' value must be >= 0, actual value '-1'' on server %mongohostport%. The full response is {"ok": 0.0, "errmsg": "BSON field 'batchSize' value must be >= 0, actual value '-1'", "code": 51024, "codeName": "Location51024"}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
org.graalvm.polyglot.PolyglotException: Command failed with error 2 (BadValue): 'cursor.batchSize must not be negative' on server %mongohostport%. The full response is {"ok": 0.0, "errmsg": "cursor.batchSize must not be negative", "code": 2, "codeName": "BadValue"}
1+
com.mongodb.MongoCommandException: Command failed with error 2 (BadValue): 'cursor.batchSize must not be negative' on server %mongohostport%. The full response is {"ok": 0.0, "errmsg": "cursor.batchSize must not be negative", "code": 2, "codeName": "BadValue"}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
org.graalvm.polyglot.PolyglotException: Query failed with error code 2 and error message 'error processing query: ns=admin.collTree: $and
1+
com.mongodb.MongoQueryException: Query failed with error code 2 and error message 'error processing query: ns=admin.collTree: $and

packages/shell-api/src/aggregation-cursor.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,17 @@ export default class AggregationCursor extends ShellApiClass {
5050
}
5151

5252
@returnsPromise
53-
forEach(f: (doc: Document) => void): Promise<void> {
53+
async forEach(f: (doc: Document) => void): Promise<void> {
5454
return this._cursor.forEach(f);
5555
}
5656

5757
@returnsPromise
58-
hasNext(): Promise<boolean> {
58+
async hasNext(): Promise<boolean> {
5959
return this._cursor.hasNext();
6060
}
6161

6262
@returnsPromise
63-
tryNext(): Promise<Document | null> {
63+
async tryNext(): Promise<Document | null> {
6464
return this._cursor.tryNext();
6565
}
6666

@@ -99,12 +99,12 @@ export default class AggregationCursor extends ShellApiClass {
9999
}
100100

101101
@returnsPromise
102-
next(): Promise<Document | null> {
102+
async next(): Promise<Document | null> {
103103
return this._cursor.next();
104104
}
105105

106106
@returnsPromise
107-
toArray(): Promise<Document[]> {
107+
async toArray(): Promise<Document[]> {
108108
return this._cursor.toArray();
109109
}
110110

packages/shell-api/src/change-stream-cursor.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,7 @@ export default class ChangeStreamCursor extends ShellApiClass {
8888
return this._cursor.closed;
8989
}
9090

91-
@returnsPromise
92-
isExhausted(): Promise<boolean> {
91+
isExhausted(): never {
9392
throw new MongoshInvalidInputError('isExhausted is not implemented for ChangeStreams because after closing a cursor, the remaining documents in the batch are no longer accessible. If you want to see if the cursor is closed use isClosed. If you want to see if there are documents left in the batch, use tryNext.');
9493
}
9594

packages/shell-api/src/collection.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -753,9 +753,8 @@ export default class Collection extends ShellApiClass {
753753
);
754754
}
755755

756-
@returnsPromise
757756
@deprecated
758-
save(): Promise<void> {
757+
save(): never {
759758
throw new MongoshInvalidInputError(
760759
'Collection.save() is deprecated. Use insertOne, insertMany, updateOne, or updateMany.'
761760
);

packages/shell-api/src/cursor.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ export default class Cursor extends ShellApiClass {
128128

129129
@serverVersions([ServerVersions.earliest, '4.0.0'])
130130
@returnsPromise
131-
count(): Promise<number> {
131+
async count(): Promise<number> {
132132
return this._cursor.count();
133133
}
134134

@@ -164,12 +164,12 @@ export default class Cursor extends ShellApiClass {
164164
}
165165

166166
@returnsPromise
167-
forEach(f: (doc: Document) => void): Promise<void> {
167+
async forEach(f: (doc: Document) => void): Promise<void> {
168168
return this._cursor.forEach(f);
169169
}
170170

171171
@returnsPromise
172-
hasNext(): Promise<boolean> {
172+
async hasNext(): Promise<boolean> {
173173
if (this._tailable) {
174174
printWarning(
175175
'If this is a tailable cursor with awaitData, and there are no documents in the batch, this method ' +
@@ -181,7 +181,7 @@ export default class Cursor extends ShellApiClass {
181181
}
182182

183183
@returnsPromise
184-
tryNext(): Promise<Document | null> {
184+
async tryNext(): Promise<Document | null> {
185185
return this._cursor.tryNext();
186186
}
187187

@@ -253,7 +253,7 @@ export default class Cursor extends ShellApiClass {
253253
}
254254

255255
@returnsPromise
256-
next(): Promise<Document | null> {
256+
async next(): Promise<Document | null> {
257257
if (this._tailable) {
258258
printWarning(
259259
'If this is a tailable cursor with awaitData, and there are no documents in the batch, this' +
@@ -308,7 +308,7 @@ export default class Cursor extends ShellApiClass {
308308
}
309309

310310
@returnsPromise
311-
size(): Promise<number> {
311+
async size(): Promise<number> {
312312
return this._cursor.count();
313313
}
314314

@@ -336,7 +336,7 @@ export default class Cursor extends ShellApiClass {
336336
}
337337

338338
@returnsPromise
339-
toArray(): Promise<Document[]> {
339+
async toArray(): Promise<Document[]> {
340340
return this._cursor.toArray();
341341
}
342342

packages/shell-api/src/decorators.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -295,11 +295,7 @@ export function shellApiClassDefault(constructor: Function): void {
295295
function markImplicitlyAwaited<T extends(...args: any) => Promise<any>>(orig: T): ((...args: Parameters<T>) => Promise<any>) {
296296
function wrapper(this: any, ...args: any[]) {
297297
const origResult = orig.call(this, ...args);
298-
return Object.prototype.toString.call(origResult) === '[object Promise]' ? addHiddenDataProperty(
299-
origResult,
300-
Symbol.for('@@mongosh.syntheticPromise'),
301-
true
302-
) : origResult;
298+
return addHiddenDataProperty(origResult, Symbol.for('@@mongosh.syntheticPromise'), true);
303299
}
304300
Object.setPrototypeOf(wrapper, Object.getPrototypeOf(orig));
305301
Object.defineProperties(wrapper, Object.getOwnPropertyDescriptors(orig));
@@ -328,10 +324,14 @@ export function topologies(topologiesArray: Topologies[]): Function {
328324
descriptor.value.topologies = topologiesArray;
329325
};
330326
}
327+
export const nonAsyncFunctionsReturningPromises: string[] = []; // For testing.
331328
export function returnsPromise(_target: any, _propertyKey: string, descriptor: PropertyDescriptor): void {
332329
const orig = descriptor.value;
333330
orig.returnsPromise = true;
334331
descriptor.value = markImplicitlyAwaited(descriptor.value);
332+
if (orig.constructor.name !== 'AsyncFunction') {
333+
nonAsyncFunctionsReturningPromises.push(orig.name);
334+
}
335335
}
336336
export function directShellCommand(_target: any, _propertyKey: string, descriptor: PropertyDescriptor): void {
337337
descriptor.value.isDirectShellCommand = true;

0 commit comments

Comments
 (0)