0

I am trying to check if an Object exists before generating a SignedUrl. However the SignedUrl returns before the headObject, generating a link that points to non-existing object.

    var params = {
        Bucket: bucket,
        Key: path,
    };

    var signedURL = "none";
    s3.headObject(params, function (err, metadata) {
        if (err && err.code === 'NotFound')
            params.Key = 'no_image.png';

        params.Expires = 900;
        s3.getSignedUrl('getObject', params, function (err, url) {
            signedURL = url;
            if (err)
                console.log("Generation of Signed url failed");
            else
                console.log("Generated Signed url");
        });
    });
    console.log("Generating PreSigned Link ... Success");
    return resolve(signedURL);

Looks like following code also does not work:

var someVar = s3.headObject(params);
someVar.then(() ...

As suggested looked at this post - Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference and it tells me why it happens but not how to fix it.

Here is the new code piece I tried by moving the return inside the callback:

    s3.headObject(params, function (err, metadata) {
        params.Expires = 900;
        if (err && err.code === 'NotFound')
            params.Key = 'no_image.png';

        s3.getSignedUrl('getObject', params, function (err, url) {
            if (err)
                return resolve("none");
            else
                return resolve(url);
        });
    });

How to use promises with AWS headObject?

user 923227
  • 2,528
  • 4
  • 27
  • 46
  • What's `resolve`, where is it defined? Probably you're supposed to call it from *inside those callbacks*. – Bergi Jun 09 '17 at 14:32
  • This is on the AWS Lambda. resolve is in the signature of the function. ` return new Promise((resolve, reject) => {` how can I resolve headObject before calling getSignedUrl - looks like the usual methods are not working. – user 923227 Jun 09 '17 at 17:43
  • @Bergi Can you please propose a solution. I am new to ES6 and node.js and the standard ways are not working. – user 923227 Jun 13 '17 at 18:25
  • As I said, move the `resolve` call inside the callback. Just what @the_bluescreen dib below, basically – Bergi Jun 13 '17 at 18:28
  • Hi @Bergi , Thanks but that did not work for me! I have added the code in the main question. Removed the variable signedURL. – user 923227 Jun 13 '17 at 22:54
  • OK, and *what* does not work? – Bergi Jun 13 '17 at 23:01
  • This piece of code is getting executed after the call to this API gets completed. So the url is missing. If I remove the headobject call then the url is generated (correct or wrong it is there). – user 923227 Jun 13 '17 at 23:10
  • "*This piece of code* (I assume you are referring to the callback that contains the `s3.getSignedUrl` call, right?) *is getting executed after the call to this API* (I assume you are referring to the `s3.headObject` API?) *gets completed.*" - is that not exactly what you want? "*So the url is missing.*" - I don't follow. – Bergi Jun 13 '17 at 23:14
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/146583/discussion-between-sumit-kumar-ghosh-and-bergi). – user 923227 Jun 13 '17 at 23:15

1 Answers1

0

I updated your code below. Basically, you are resolving the promise before finish your calls.

var params = {
  Bucket: bucket,
  Key: path,
};

var signedURL = "none";

s3.headObject(params, function (err, metadata) {
    params.Expires = 900;

    if (err && err.code === 'NotFound') {
        params.Key = 'no_image.png';
        resolve(signedURL);
    } else {
        s3.getSignedUrl('getObject', params, function (err, url) {
           signedURL = url;
           if (err) {
              console.log("Generation of Signed url failed");
              reject(url);
           } else {
             resolve(signedURL);
           }
        });
    }
});
the_bluescreen
  • 3,126
  • 2
  • 18
  • 31
  • Here I have a file named no_image.png I want to generate the signed url for that when the actual url is not found. This way I am not able to do that. Hence, I have tried adding the s3.getSignedUrl to both the if part and else part but the effect remains same. – user 923227 Jun 09 '17 at 16:47