node.jsamazon-web-servicesnode-promisify

util.promisify converts async functions that use callbacks to Promises. Why doesn't it work with AWS S3.upload which follows that format?


Question: util.promisify converts an async function that uses the error-first callback style to a Promise. However it doesn't seem to work with AWS' S3.upload (scroll down to .upload) which is an async function that uses the error-first callback format.

Original format:

const params = {Bucket: 'bucket', Key: 'key', Body: stream};
s3.upload(params, function(err, result) {
    if (err) {
        throw new Error(err);
    } else {
        console.log(result);
    }
});

Promisify format:

const params = {Bucket: 'bucket', Key: 'key', Body: stream};
const s3Upload = util.promisify(s3.upload);
s3Upload(params)
    .then( (result) => {
        console.log(result);
    })
    .catch( (err) => {
        throw new Error(err);
    });

However used in this manner s3.upload throws an error,

TypeError: service.getSignatureVersion is not a function

If util.promisify doesn't necessarily work for every async function that uses a callback is there a way to determine beforehand if a function will work with it? Or alternately does it take trial and error to determine if util.promisify will work?


Solution

  • Geoffrey has explained why this probably doesn't work for the code you tried, but even better would be to use the promise support built-into the AWS interface:

    const params = {Bucket: 'bucket', Key: 'key', Body: stream};
    s3.upload(params).promise().then((result) => {
        console.log(result);
    }).catch( (err) => {
        console.log(err);
        throw err;
    });
    

    AWS documentation here: https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/using-promises.html