Reputation: 4619
While trying to get a signed URL for a getObject
I am getting the following error from the aws-sdk
library:
<proj-dir>\node_modules\aws-sdk\lib\util.js:983
return str && str.indexOf('arn:') === 0 && str.split(':').length >= 6;
^
TypeError: str.indexOf is not a function
at Object.validateARN [as validate] (<proj-dir>\node_modules\aws-sdk\lib\util.js:983:25)
at features.constructor.hasBucketInParams [as isAccessPointApplicable] (<proj-dir>\node_modules\aws-sdk\lib\services\s3.js:180:2
3)
at features.constructor.setupRequestListeners (<proj-dir>\node_modules\aws-sdk\lib\services\s3.js:126:14)
at features.constructor.addAllRequestListeners (<proj-dir>\node_modules\aws-sdk\lib\service.js:276:10)
at features.constructor.makeRequest (<proj-dir>\node_modules\aws-sdk\lib\service.js:203:10)
at features.constructor.getSignedUrl (<proj-dir>\node_modules\aws-sdk\lib\services\s3.js:1026:24)
at Object.<anonymous> (<proj-dir>\s3-test.js:101:8)
at Module._compile (internal/modules/cjs/loader.js:955:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
at Module.load (internal/modules/cjs/loader.js:811:32)
Other S3 calls (like listBuckets
) are working fine. Here's my test file:
const S3 = require('./utils/s3Util');
const C = require('./utils/constants');
const _ = require('lodash');
// other code...
S3.svc.getSignedUrl('getObject', { Bucket: C.S3_BUCKET, Key: 'TestFrequencyCount.java', Expires: 60 }).promise()
.then(retVal => {
console.log("Return value:", retVal);
}).catch(err => {
console.log("Error::", err);
});
The s3Util.js
file:
const C = require('./constants');
const AWS = require('aws-sdk');
const keys = require("../config/aws-config.json");
// AWS.config.update(keys);
const s3 = new AWS.S3({...keys, apiVersion: C.S3_API_VER, signatureVersion: 'v4' });
module.exports = Object.freeze({
svc: s3,
});
I was using aws-sdk
version 2.610.0, then updated that to 2.621.0, but the problem remains.
Even tried by changing the way I was loading the AWS account credentials (will use an IAM user once I have things figured out) based on a combination of this note from AWS SDK documentation:
Note: You must ensure that you have static or previously resolved credentials if you call this method synchronously (with no callback), otherwise it may not properly sign the request. If you cannot guarantee this (you are using an asynchronous credential provider, i.e., EC2 IAM roles), you should always call this method with an asynchronous callback.
and the solution given at Node.js and aws credentials error - json (which suggested not using AWS.config.loadFromPath(path)
but instead loading the parameters directly through AWS.config.update(...)
), but to no avail.
In deseparation I tried the callback version as well, but as expected it gave the same result:
S3.svc.getSignedUrl('getObject', { Bucket: C.S3_BUCKET, Key: 'TestFrequencyCount.java', Expires: 60 }, (err, retVal) => {
if (err) {
console.log("Error::", err);
} else {
console.log("Return value:", retVal);
}
});
Upvotes: 0
Views: 1997
Reputation: 4619
The error was with the definition of C.S3_BUCKET
: it should have been used instead as: C.S3_BUCKET[process.env.NODE_ENV]
.
Upvotes: 2
Reputation: 599
str
variable is probably an object, not a string or array, so indexOf
method cannot be applied to it. Use console.log(str) to confirm this.
Upvotes: 1