aws-sdk-js: bluebird with aws-sdk: Cannot promisify an API that has normal methods with 'Async'-suffix

Seems there is a bug when working with bluebird@3.5.1 and aws-sdk@2.305.0 const bluebird = require('bluebird'); const AWS = require('aws-sdk'); const AWSSQS = new AWS.SQS(); bluebird.promisifyAll(AWSSQS);

trigger an error: TypeError: Cannot promisify an API that has normal methods with 'Async'-suffix See http://goo.gl/MqrFmX

the problem probably because you added function with ‘Async’ suffix.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 15
  • Comments: 17 (2 by maintainers)

Commits related to this issue

Most upvoted comments

We had same issue… the root cause of our issue has to do with dynasty package not locking into one version ^ of aws-sdk.

Also AWS-SDK team should of never changed a callback to a promise in a minor release as this is a breaking change.

@DanielSuperSonic It shouldn’t be necessary to promisify the SDK. If promises are available in your environment, any operation can return a promise by calling the promise() method on the operation’s return value:

// with callbacks
sqs.listQueues(function(err, data) {});

// using .promise
sqs.listQueues().promise();

If you specifically want to use the bluebird implementation of promises, you can configure the SDK to use that instead:

AWS.config.setPromiseDependency(require('bluebird'));

@jasonfutch You can still use callbacks with the SDK. To avoid making a breaking change, we only return promises on operations if you explicitly call the promise() method on the operation’s return value.

@chrisradek regarding https://github.com/aws/aws-sdk-js/issues/2229#issuecomment-417386675 :

It shouldn’t be necessary to promisify the SDK. If promises are available in your environment, any operation can return a promise by calling the promise() method on the operation’s return value:

// with callbacks
sqs.listQueues(function(err, data) {});

// using .promise
sqs.listQueues().promise();

I initially liked that path, but after moving a chunk of existing code to .promise(), I’m going to stay with Bluebird,

Because all things considered, promisifying callback-based APIs is a pattern I’m okay with, and AWS promise() sounds neat, but makes mocking a bit more painful and a lot uglier:

// stubbing a promisified DynamoDB.DocumentClient
sinon.stub(dynamo.documentClient, 'putAsync')
     .resolves({ Attributes: response });

// stubbing a DynamoDB.DocumentClient using promise()
sinon.stub(dynamo.documentClient, 'put')
     .returns({ promise: () => (new Promise(resolve => (resolve({ Attributes: response })))) });

What’s wrong with using the latest version of the sdk and a different suffix?

bluebird.promisifyAll(AWSSQS, {suffix: 'Promise'})

What’s wrong with using the latest version of the sdk and a different suffix?

This would require existing code (using …Async until now) to be modified, which clearly should not be the intent of a patch semver release.

Thanks @jasonfutch. Moving back and pegging aws-sdk-js to version 2.304.0 is the perfect workaround for now.

We can change suffix while doing promisifyAll Promise.promisifyAll( Object target, [Object { suffix: String="Async", multiArgs: boolean=false, filter: boolean function(String name, function func, Object target, boolean passesDefaultFilter), promisifier: function(function originalFunction, function defaultPromisifier) } options] ) -> Object http://bluebirdjs.com/docs/api/promise.promisifyall.html

I changed to ‘Async2’ and it works well