aws-sdk-js-v3
aws-sdk-js-v3 copied to clipboard
updating v2 to v3. getting error: shared-ini-file-loader/dist-cjs/loadSharedConfigFiles. reading undefined (then)
Describe the bug
the code base has been using v2 with no issues and during migration to v3 (manual as well as using 'codemod') i keep getting the same error. the only changes have been in the package update and necessary syntax/logic changes. The error seems to change from one file to another and the only constant is that its reading 'undefined' (reading then)
/shared/node_modules/@aws-sdk/shared-ini-file-loader/dist-cjs/loadSharedConfigFiles.js:16
.then(parseIni_1.parseIni)
^
TypeError: Cannot read properties of undefined (reading 'then')
Expected Behavior
expected to haver all tests pass in version 3 the same way they did in version 2. there was only the minimal version update/syntax change to version 3, the tests should all stay passing. Also another expectation is that the tests pass since they are mocking the services and not actually using the aws service in tests.
Current Behavior
random tests error out. meaning that each time the tests are run, a different test will fail. but the error is the same error regarding 'loadSharedConfigFiles'
Reproduction Steps
****package.json-
"dependencies": {
"@aws-sdk/client-ec2": "^3.332.0",
"@aws-sdk/client-marketplace-metering": "^3.332.0",
"@aws-sdk/client-rds": "^3.332.0",
"@aws-sdk/client-s3": "^3.332.0",
"@aws-sdk/client-sts": "^3.332.0",
*the old v2 aws.js code-
import AWS from 'aws-sdk';
const s3 = new AWS.S3({ proxy: process.env.HTTP_PROXY });
const sts = new AWS.STS();
const ec2 = new AWS.EC2();
const rds = new AWS.RDS();
const metering = new AWS.MarketplaceMetering();
****the updated v3 aws.js-
import { STSClient } from ‘@aws-sdk/client-sts’;
import { EC2Client } from ‘@aws-sdk/client-ec2’;
import { RDSClient } from ‘@aws-sdk/client-rds’;
import { S3Client } from ‘@aws-sdk/client-s3’;
import { MarketplaceMeteringClient } from ‘@aws-sdk/client-marketplace-metering’;
const sts = new STSClient();
const s3 = new S3Client();
const ec2 = new EC2Client();
const rds = new RDSClient();
const metering = new MarketplaceMeteringClient();
Possible Solution
i have no idea at this point honestly.
Additional Information/Context
i have the most minimal changes as possible where only the package.json and the way the new v3 is imported and i have another branch where ive made major changes to the test files that would error out. this is only an issue with running the tests. this happens in my local as well as remote. ive had others run the same branch of the repo in their environment and they have gotten the same error so im able to rule out that its a config/configuration file issue.
SDK version used
3.332.0
Environment details (OS name and version, etc.)
AlmaLinux release 9.2 (Turquoise Kodkod)
Hi @Dahlak76, sorry to hear about your issues. It is really weird the issue that you are having, because if we follow what could cause the exception in the line you posted, based on the implementation it should never fail. Lets quick check, the exception is thrown from this line, so that means the function slurpFile is returning undefined, but if we check the implementation for slurpFile here it will only return undefined if the readFile function from fs module returns undefined, which is an improbable case. I tested the readFile function, and it always returns either the content of the file as buffer, or an exception is thrown if the file does not exists. I also tried to reproduce this issue on my end with the steps that you provided but I was not able to.
Could you please confirm if you are using nodejs runtime?, and if so, could you please provide the version. You can also provide any other details that you think will be helpful to reproduce this.
Thanks!
Transferring to v3 repo since it is a v3 issue.
Hi @yenfryherrerafeliz Thank you for looking into this.
I totally agree with your assessment and its not making sense. I'm using nodejs runtime in both local and dev environments
~/.nvm/versions/node/v16.20.0/bin/node
the package went from the sole aws-sdk (v2) to the separate components that the new (v3) requires so
i deleted this:
` "aws-sdk": "^2.1153.0",
`and installed these instead:
``` "dependencies": {
"@aws-sdk/client-ec2": "^3.332.0",
"@aws-sdk/client-marketplace-metering": "^3.332.0",
"@aws-sdk/client-rds": "^3.332.0",
"@aws-sdk/client-s3": "^3.332.0",
"@aws-sdk/client-sts": "^3.332.0",
I have two git branches im working on. One of them ive made changes to only the aws.js file that the packages are imported, added to a variable and exported for use throughout the code-base (this is the branch I used for this issues ticket thats shown above). The second repo, I've edited/updated to v3 in the same aws.js file and some other files and the tests files that would error out, i updated the file as well as the corresponding jest test file from the v2 syntax to the v3 syntax (My understanding is that v2 syntax is compatable with v3 package imports, please correct me if I'm wrong). This is an example of the changes to the second branch: I'd import into the parent aws.js file like this
... DescribeImagesCommand,
DescribeSubnetsCommand
} from '@aws-sdk/client-ec2';
import { RDSClient } from '@aws-sdk/client-rds';
import { S3Client } from '@aws-sdk/client-s3';
then for example in the describe-subnets.js file I'd import it like this
import { ec2, DescribeSubnetsCommand } from '../../../models/aws/aws'; then modify the code to use 'send' on a new DescribeSubnetsCommand(params) like this
const describeSubnets = async (subnetList, params) => {
const command = new DescribeSubnetsCommand(params);
let describeSubnetsResult;
try {
describeSubnetsResult = await ec2.send(command);
} catch (error) {
throw new AwsError(
`Error occured during ec2.describeSubnets: ${error}`,
);
}
if(!describeSubnetsResult){
return subnetList;
}
const nextToken = describeSubnetsResult.NextToken;
if (nextToken !== undefined)
While the errors are all coming from different Jest tests it's not making sense that that constant error comes up or why given your above check of the code. Also, the tests are all mocking so actual credentials shouldnt be an issue and even if they were using the credentials, the v2 has been using it just fine and as expected until the update to v3.
@Dahlak76, thanks for providing this information. Since you mentioned that this issue happens from tests using jest, I think the problem here could be that fs.readFile is being mocked, and its return value is set, or not even set, to undefined instead of a promise. Would it be possible for you to confirm this?
Regarding some of your questions / comments:
(My understanding is that v2 syntax is compatible with v3 package imports, please correct me if I'm wrong)
This is not entirely true, but it will depend on how you use the client. For example, if using the modular feature of v3 you would probably import each command separated, but if you want to keep the code similar to v2 then, you will probably import the wrapper of the client that contains all the operation/methods. For example, the wrapper for S3Client is S3.
then for example in the describe-subnets.js file I'd import it like this import { ec2, DescribeSubnetsCommand } from '../../../models/aws/aws'; then modify the code to use 'send' on a new DescribeSubnetsCommand(params) like this
Why don't you import from "@aws-sdk/client-ec2" instead? as follow:
import { ec2, DescribeSubnetsCommand } from "@aws-sdk/client-ec2"
I look forward for your response.
Thanks!
Hi @yenfryherrerafeliz,
Thank you again.
I checked and there is nowhere in our codebase where fs.readFile is being mocked, it also does exist not as a dependency or devDependency.
RE: some of your comments
For example, if using the modular feature of v3 you would probably import each command separated, but if you want to keep the code similar to v2 then, you will probably import the wrapper of the client that contains all the operation/methods. For example, the wrapper for S3Client is S3.
I have tried it both ways and still same errors. For the bare-bones branch I am using S3 instead of S3Client and vice versa for the other branch. I'm thinking that using the wrapper like S3 would enable to not have to change the test files on the commands from the existing await S3.getObject({...})); to await S3.send(new GetObjectCommand({...}));throughout each test file.
Why don't you import from "@aws-sdk/client-ec2" instead? as follow:
import { ec2, DescribeSubnetsCommand } from "@aws-sdk/client-ec2"
there is an aws/aws.js file where all the clients get imported into and and then are created using the new keyword and then exported throughout the codebase like this
import { S3 } from '@aws-sdk/client-s3';
import { STS } from '@aws-sdk/client-sts';
import { EC2 } from '@aws-sdk/client-ec2';
import { RDS } from '@aws-sdk/client-rds';
import { MarketplaceMeteringClient } from '@aws-sdk/client-marketplace-metering';
const s3 = new S3({ proxy: process.env.HTTP_PROXY });
const sts = new STS({});
const ec2 = new EC2({});
const rds = new RDS({});
const metering = new MarketplaceMeteringClient({});
export { ec2, rds, metering, s3, sts };
so thats why in the example file snippet i sent its has it as import { ec2 } from '../../../models/aws/aws'; instead of from from "@aws-sdk/client-ec2". Is there anything with the v2 to v3 changes that would require the client be imported directly into each file used and also have each instance be created in that same file? I dont think so but figure I'd ask just to make sure.
Using the current syntax where I use the wrapper approach
import { S3 } from '@aws-sdk/client-s3';
import { STS } from '@aws-sdk/client-sts';
const s3 = new S3({ proxy: process.env.HTTP_PROXY });
const sts = new STS({});
I'm understanding right that all the new instances that are created where nothing is passed like in const sts = new STS({}); means that the default config that is stored and shows when aws configure is run is what is passed in? And in the example for the S3 const s3 = new S3({ proxy: process.env.HTTP_PROXY }); the default is used for all properties except for proxy where the variable passed in is used?
I'm honestly still puzzled as to why this issue persists. If its not fs.readFile related, are there any other ideas that you think I could look into? Also, is there any other information that would help troubleshoot?
Hi @yenfryherrerafeliz,
I was wondering, does the @aws-sdk/shared-ini-file-loader package need to be installed/used for version 3? I have been assuming not since it hasnt been needed for version 2.
can someone please help I have the same issue
help having the same problem
Hey all - sorry for the long silence here.
The problem appears to stem from the user's configuration settings rather than an issue with the SDK's runtime environment. However, it would be helpful to determine if the latest or a recent version of the SDK still exhibits this behavior. If someone could provide step-by-step instructions to reproduce the issue along with a minimal code example, it would aid in further investigation of the matter.
This issue has not received a response in 1 week. If you still think there is a problem, please leave a comment to avoid the issue from automatically closing.