From ae64bb4da837e3f37a1f10a29b7575cd5461724a Mon Sep 17 00:00:00 2001 From: Matt Broadstone Date: Sun, 3 Feb 2019 10:41:43 -0500 Subject: [PATCH] fix(with-transaction): throw a useful error on invalid return type --- lib/sessions.js | 15 ++++++++++++++- lib/utils.js | 13 ++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/sessions.js b/lib/sessions.js index 93a4a09d9..3cb00b424 100644 --- a/lib/sessions.js +++ b/lib/sessions.js @@ -11,6 +11,7 @@ const MongoNetworkError = require('./error').MongoNetworkError; const MongoWriteConcernError = require('./error').MongoWriteConcernError; const Transaction = require('./transactions').Transaction; const TxnState = require('./transactions').TxnState; +const isPromiseLike = require('./utils').isPromiseLike; function assertAlive(session, callback) { if (session.serverSession == null) { @@ -328,7 +329,19 @@ function userExplicitlyEndedTransaction(session) { function attemptTransaction(session, startTime, fn, options) { session.startTransaction(options); - return fn(session) + let promise; + try { + promise = fn(session); + } catch (err) { + promise = Promise.reject(err); + } + + if (!isPromiseLike(promise)) { + session.abortTransaction(); + throw new TypeError('Function provided to `withTransaction` must return a Promise'); + } + + return promise .then(() => { if (userExplicitlyEndedTransaction(session)) { return; diff --git a/lib/utils.js b/lib/utils.js index 539e9d656..73adaddad 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -106,6 +106,16 @@ function collationNotSupported(server, cmd) { return cmd && cmd.collation && maxWireVersion(server) < 5; } +/** + * Checks if a given value is a Promise + * + * @param {*} maybePromise + * @return true if the provided value is a Promise + */ +function isPromiseLike(maybePromise) { + return maybePromise && typeof maybePromise.then === 'function'; +} + module.exports = { uuidV4, calculateDurationInMs, @@ -113,5 +123,6 @@ module.exports = { collationNotSupported, retrieveEJSON, retrieveKerberos, - maxWireVersion + maxWireVersion, + isPromiseLike };