Skip to content

Commit 6fdf08b

Browse files
committed
feat(NODE-2014): return the result of provided callback
1 parent 14427d1 commit 6fdf08b

File tree

6 files changed

+60
-20
lines changed

6 files changed

+60
-20
lines changed

src/collection.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ import {
8686
Callback,
8787
checkCollectionName,
8888
DEFAULT_PK_FACTORY,
89-
emitWarningOnce,
9089
MongoDBNamespace,
9190
normalizeHintField,
9291
resolveOptions

src/mongo_client.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ export interface MongoClientOptions extends BSONSerializeOptions, SupportedNodeC
273273
}
274274

275275
/** @public */
276-
export type WithSessionCallback = (session: ClientSession) => Promise<any>;
276+
export type WithSessionCallback<T = any> = (session: ClientSession) => Promise<T>;
277277

278278
/** @internal */
279279
export interface MongoClientPrivate {
@@ -643,12 +643,12 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> {
643643
* @param options - Optional settings for the command
644644
* @param callback - An callback to execute with an implicitly created session
645645
*/
646-
withSession(callback: WithSessionCallback): Promise<void>;
647-
withSession(options: ClientSessionOptions, callback: WithSessionCallback): Promise<void>;
648-
withSession(
649-
optionsOrOperation?: ClientSessionOptions | WithSessionCallback,
650-
callback?: WithSessionCallback
651-
): Promise<void> {
646+
withSession<T>(callback: WithSessionCallback<T>): Promise<T>;
647+
withSession<T>(options: ClientSessionOptions, callback: WithSessionCallback<T>): Promise<T>;
648+
withSession<T>(
649+
optionsOrOperation?: ClientSessionOptions | WithSessionCallback<T>,
650+
callback?: WithSessionCallback<T>
651+
): Promise<T> {
652652
const options = {
653653
// Always define an owner
654654
owner: Symbol(),
@@ -666,15 +666,17 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> {
666666
const session = this.startSession(options);
667667

668668
return maybeCallback(async () => {
669+
let value;
669670
try {
670-
await withSessionCallback(session);
671+
value = await withSessionCallback(session);
671672
} finally {
672673
try {
673674
await session.endSession();
674675
} catch {
675676
// We are not concerned with errors from endSession()
676677
}
677678
}
679+
return value;
678680
}, null);
679681
}
680682

src/sessions.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export interface ClientSessionOptions {
6161
}
6262

6363
/** @public */
64-
export type WithTransactionCallback<T = void> = (session: ClientSession) => Promise<T>;
64+
export type WithTransactionCallback<T = any> = (session: ClientSession) => Promise<T>;
6565

6666
/** @public */
6767
export type ClientSessionEvents = {
@@ -470,10 +470,7 @@ export class ClientSession extends TypedEventEmitter<ClientSessionEvents> {
470470
* @param options - optional settings for the transaction
471471
* @returns A raw command response or undefined
472472
*/
473-
withTransaction<T = void>(
474-
fn: WithTransactionCallback<T>,
475-
options?: TransactionOptions
476-
): Promise<Document | undefined> {
473+
withTransaction<T>(fn: WithTransactionCallback<T>, options?: TransactionOptions): Promise<T> {
477474
const startTime = now();
478475
return attemptTransaction(this, startTime, fn, options);
479476
}
@@ -615,12 +612,14 @@ function attemptTransaction<TSchema>(
615612
}
616613

617614
return promise.then(
618-
() => {
615+
value => {
619616
if (userExplicitlyEndedTransaction(session)) {
620-
return;
617+
return value;
621618
}
622619

623-
return attemptTransactionCommit(session, startTime, fn, options);
620+
return attemptTransactionCommit(session, startTime, fn, options).then(() => {
621+
return value;
622+
});
624623
},
625624
err => {
626625
function maybeRetryOrThrow(err: MongoError): Promise<any> {

test/integration/transactions/transactions.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,19 @@ describe('Transactions', function () {
9090
expect(withTransactionResult).to.be.undefined;
9191
});
9292

93-
it('should return raw command when transaction is successfully committed', async () => {
93+
it('should return callback return value when transaction is successfully committed', async () => {
9494
const session = client.startSession();
9595

9696
const withTransactionResult = await session
9797
.withTransaction(async session => {
9898
await collection.insertOne({ a: 1 }, { session });
99-
await collection.findOne({ a: 1 }, { session });
99+
return await collection.findOne({ a: 1 }, { session });
100100
})
101101
.finally(async () => await session.endSession());
102102

103103
expect(withTransactionResult).to.exist;
104104
expect(withTransactionResult).to.be.an('object');
105-
expect(withTransactionResult).to.have.property('ok', 1);
105+
expect(withTransactionResult).to.have.property('a', 1);
106106
});
107107

108108
it('should throw when transaction is aborted due to an error', async () => {

test/unit/mongo_client.test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,3 +873,25 @@ describe('MongoOptions', function () {
873873
});
874874
});
875875
});
876+
877+
describe('MongoClient', function () {
878+
describe('#withSession', function () {
879+
const client = new MongoClient('mongodb://localhost:27017');
880+
881+
context('when the callback returns a value', function () {
882+
it('returns the value in the promise', async function () {
883+
const value = await client.withSession(async () => {
884+
return 'test';
885+
});
886+
expect(value).to.equal('test');
887+
});
888+
});
889+
890+
context('when the callback does not return a value', function () {
891+
it('does not return a value in the promise', async function () {
892+
const value = await client.withSession(async () => {});
893+
expect(value).to.equal(undefined);
894+
});
895+
});
896+
});
897+
});

test/unit/sessions.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,24 @@ describe('Sessions - unit', function () {
3232
});
3333
});
3434

35+
describe('#withTransaction', function () {
36+
context('when the callback returns a value', function () {
37+
it('returns the value in the promise', async function () {
38+
const value = await session.withTransaction(async () => {
39+
return 'test';
40+
});
41+
expect(value).to.equal('test');
42+
});
43+
});
44+
45+
context('when the callback does not return a value', function () {
46+
it('does not return a value in the promise', async function () {
47+
const value = await session.withTransaction(async () => {});
48+
expect(value).to.equal(undefined);
49+
});
50+
});
51+
});
52+
3553
describe('advanceClusterTime()', () => {
3654
it('should throw an error if the input cluster time is not an object', function () {
3755
const invalidInputs = [undefined, null, 3, 'a'];

0 commit comments

Comments
 (0)