"use strong";
"use strict";

module.exports = function maybePromiseFactory(promiseConstructor) {
	return function maybePromise(f, ...args) {
		let result;
		try {
			result = f.apply(null, args);
		} catch(e) {
			return promiseConstructor.reject(e);
		}

		if(result instanceof promiseConstructor) {
			return result;
		} else if(result instanceof Error) {
			return promiseConstructor.reject(result);
		} else {
			return promiseConstructor.resolve(result);
		}
	};
}

"use strong";
"use strict";

/**
 * Constructs a maybePromise function.
 * @param {class} promiseConstructor A Promise implementation (e.g. `Bluebird` or `Promise`)
 * @param {boolean} [useAnyThenable] If truthy, any Promise implementation is considered a promise; otherwise,
 * only instances of the `promiseConstructor` are considered promises.
 * @returns {Function} A function that takes a function and arguments. Invokes the function with arguments. If
 * the result of the function is a promise, it is returned. Otherwise, the result is converted to a promise.
 * If an error is thrown, a rejected promise is returned.
 */
module.exports = function maybePromiseFactory(promiseConstructor, useAnyThenable) {
	return function maybePromise(f, ...args) {
		let result;
		try {
			result = f.apply(null, args);
		} catch(e) {
			return promiseConstructor.reject(e);
		}

		if(result instanceof promiseConstructor || (useAnyThenable && result && typeof result.then === 'function')) {
			return result;
		} else {
			return promiseConstructor.resolve(result);
		}
	};
}

Add useAnyThenable option; don't reject if a synchronous function for returning an Error
Add useAnyThenable option; don't reject if a synchronous function for returning an Error

* The synchronous equivalent to rejecting a promise should really just be throwing an error. Returning an instanceof Error might not be a valid reason to reject a promise -- what if the method is `getValidationError`?
* If integrating with third-party modules that may use different Promise libraries, I added a second parameter `useAnyThenable`. If truthy, it considers any object with a `then` method to be a promise, which follows the spec for `Promise.resolve` in MDN for determining whether a given object is a Promise. This allows the developer to create a `maybePromiseFactory` with the built-in ES6 Promise and still accept Bluebird or other implementations of promises correctly.