Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: Value is not an object: undefined #36

Closed
txm062 opened this issue Jan 25, 2023 · 12 comments
Closed

TypeError: Value is not an object: undefined #36

txm062 opened this issue Jan 25, 2023 · 12 comments
Assignees
Labels
bug Something isn't working

Comments

@txm062
Copy link

txm062 commented Jan 25, 2023

I'm trying to post to SNS and thought that your signatureV4 example might work. However even whilst using the example provided i get the error TypeError: Value is not an object: undefined. from the below line.

const signer = new SignatureV4({
        service: 'sns',
        region: awsConfig.region,
        credentials: {
            accessKeyId: awsConfig.accessKeyId,
            secretAccessKey: awsConfig.secretAccessKey,
            sessionToken: awsConfig.sessionToken,
        },
    })

I've literally just copied the example except dropping the first .js from the import. Does this work for SNS or what am i missing?
As i said im just using the defaults and havent changed it for POST etc yet

import http from 'k6/http'

import { AWSConfig, SignatureV4 } from 'https://jslib.k6.io/aws/0.7.1/kms.js'

const awsConfig = new AWSConfig({
  region: "eu-west-1",
  accessKeyId: "example",
  secretAccessKey: "example",
  sessionToken: "example",
})

export default function () {
    /**
     * In order to be able to sign an HTTP request's,
     * we need to instantiate a SignatureV4 object.
     */
    const signer = new SignatureV4({
        service: 'sns',
        region: awsConfig.region,
        credentials: {
            accessKeyId: awsConfig.accessKeyId,
            secretAccessKey: awsConfig.secretAccessKey,
            sessionToken: awsConfig.sessionToken,
        },
    })

    /**
     * The sign operation will return a new HTTP request with the
     * AWS signature v4 protocol headers added. It returns an Object
     * implementing the SignedHTTPRequest interface, holding a `url` and a `headers`
     * properties, ready to use in the context of k6's http call.
     */
    const signedRequest = signer.sign(
        /**
         * HTTP request description
         */
        {
            /**
             * The HTTP method we will use in the request.
             */
            method: 'GET',

            /**
             * The network protocol we will use to make the request.
             */
            protocol: 'https',

            /**
             * The hostname of the service we will be making the request to.
             */
            hostname: 'test-jslib-aws.s3.us-east-1.amazonaws.com',

            /**
             * The path of the request.
             */
            path: '/bonjour.txt',

            /**
             * The headers we will be sending in the request.
             */
            headers: {},

            /**
             * Whether the URI should be escaped or not.
             */
            uriEscapePath: false,

            /**
             * Whether or not the body's hash should be calculated and included
             * in the request.
             */
            applyChecksum: false,
        }
    )

    http.get(signedRequest.url, { headers: signedRequest.headers })
}
@txm062
Copy link
Author

txm062 commented Jan 25, 2023

import was wrong in the example for me.

import { AWSConfig, SignatureV4 } from 'https://jslib.k6.io/aws/0.7.1/aws.js'

has gotten me a step further

@txm062
Copy link
Author

txm062 commented Jan 26, 2023

This problem also occurs with sqs, even if i change the import to import { AWSConfig, SQSClient } from 'https://jslib.k6.io/aws/0.7.1/sqs.js' is there something im doing wrong?

import exec from 'k6/execution';

import { AWSConfig, SQSClient } from 'https://jslib.k6.io/aws/0.7.1/aws.js'

const awsConfig = new AWSConfig({
    region: 'ex',
    accessKeyId: 'ex',
    secretAccessKey: 'ex',
    sessionToken: 'ex',
})

const sqs = new SQSClient(awsConfig)
const testQueue = 'ex'

export default function () {
    // If our test queue does not exist, abort the execution.
    const queuesResponse = sqs.listQueues()
    if (queuesResponse.queueUrls.filter((q) => q === testQueue).length == 0) {
        exec.test.abort()
    }

    // Send message to test queue
   const res = sqs.sendMessage({
        queueUrl: testQueue,
        messageBody: JSON.stringify({
            value: '123',
        }),
    })

    console.log(res)
}

@oleiade
Copy link
Member

oleiade commented Jan 26, 2023

Hey @txm062 I'm gonna check if I can reproduce and get back to you as soon as I have news 👍🏻

@oleiade oleiade self-assigned this Jan 26, 2023
@oleiade oleiade added the bug Something isn't working label Jan 26, 2023
@jaswanthm
Copy link

jaswanthm commented Feb 9, 2023

Hey team, I tried to clone the repo and run the tests in the library locally. But I ended up getting the same error. I'm in the process of adding a new redshift client to this repo.

Here are the logs when I ran the tests in verbose mode k6 run tests/index.js --verbose. Hope that helps debug the issue better. Thanks 🙏🏻

I've been able to run an older version of the library (before adding the new signature concept). So I've been working on that for time being.

DEBU[0002] Starting emission of VU metrics...            component=engine
DEBU[0002] setup() aborted by error                      error="TypeError: prototype is not an object\n\tat y (file:///Users/jas.manigundan/Projects/K6/k6-jslib-aws/build/aws.js:2:3520(3))\n\tat e (file:///Users/jas.manigundan/Projects/K6/k6-jslib-aws/build/aws.js:2:4095(7))\n" phase=local-execution-scheduler-run
DEBU[0002] Execution scheduler terminated                component=engine error="TypeError: prototype is not an object\n\tat y (file:///Users/jas.manigundan/Projects/K6/k6-jslib-aws/build/aws.js:2:3520(3))\n\tat e (file:///Users/jas.manigundan/Projects/K6/k6-jslib-aws/build/aws.js:2:4095(7))\n"
DEBU[0002] Processing metrics and thresholds after the test run has ended...  component=engine
DEBU[0002] run: execution scheduler returned an error    component=engine error="TypeError: prototype is not an object\n\tat y (file:///Users/jas.manigundan/Projects/K6/k6-jslib-aws/build/aws.js:2:3520(3))\n\tat e (file:///Users/jas.manigundan/Projects/K6/k6-jslib-aws/build/aws.js:2:4095(7))\n"
DEBU[0005] Stopping 0 outputs...                         component=engine


@oleiade
Copy link
Member

oleiade commented Apr 21, 2023

Hey folks 👋🏻

Sorry for the rather long delay, it took us quite some time to have the bandwidth to get back to this issue. We have just published version v0.7.2, which I believe might address the issues you've been encountering.

My findings where that the AWSConfig was not finding the values it expected to find (one of them was misnamed), and the error was not handled until much later in the execution path, which led to this very confusing error 🤦🏻

Can you try it out using the https://jslib.k6.io/aws/0.7.2 import path, and let me know if that resolves the issue for you? 🙇🏻

@rtim75
Copy link

rtim75 commented May 24, 2023

I'm trying to use k6 to test our Appsync API and getting somewhat similar error. I combined 2 examples from k6 docs/blogposts:

  1. graphql load-testing
  2. aws signature
import http from 'k6/http'
import { AWSConfig, SignatureV4 } from 'https://jslib.k6.io/aws/0.7.2/aws.js'

const environment = {.......}
const query = `
  .....
`
const headers = {
	'Content-Type': 'application/json',
	Accept: '*/*',
	'Accept-Encoding': 'gzip, deflate, br',
	Connection: 'keep-alive',
	'X-Session': environment.X_SESSION,
}

export default function() {
	const awsConfig = new AWSConfig({
		region: environment.aws_region,
		accessKeyId: environment.AccessKeyId,
		secretAccessKey: environment.SecretKey,
		sessionToken: environment.SessionToken,
	})

	const signer = new SignatureV4({
		service: 'appsync',
		region: awsConfig.region,
		credentials: {
			accessKeyId: awsConfig.accessKeyId,
			secretAccessKey: awsConfig.secretAccessKey,
			sessionToken: awsConfig.sessionToken,
		},
	})

	const signedRequest = signer.sign(
		{
			method: 'POST',
			protocol: 'https',
			hostname: environment.PUBLISHER_API_ENDPOINT_2_0,
			headers: headers,
			applyChecksum: true,
		},
	)

	http.post(signedRequest.url, JSON.stringify({ query }), {
		headers: signedRequest.headers,
	})
}

this script results in the next error:

ERRO[0000] TypeError: Cannot read property 'signingDate' of undefined
        at value (webpack://k6-jslib-aws/./src/internal/signature.ts:84:12(2))
        at file:///.../k6-script.js:206:2(53)  executor=per-vu-iterations scenario=default source=stacktrace

Sorry, I cannot provide query and environmnet details for obvious reasons.

@oleiade
Copy link
Member

oleiade commented Jun 6, 2023

Hey @rtim75

It looks like the way we had defined how we handle the second optional argument of the sign method could lead to this issue indeed.

The master branch has a fix for this included. The fix will land in v0.8.0 of the library, but in the meantime, you might want to grab the build file from the master branch's build folder and use that instead of the jslib resource.

Let me know if that works for you 🙇

@rtim75
Copy link

rtim75 commented Jun 6, 2023

Thanks, @oleiade. I'll try this out this week 🙇

@rtim75
Copy link

rtim75 commented Jun 7, 2023

@oleiade
I had a chance to try this out, and now I'm getting another error. The code is the same as in my previous comment. The only thing that changed is the import:

import {AWSConfig, SignatureV4} from 'https://raw.githubusercontent.com/grafana/k6-jslib-aws/main/build/aws.js'

now I'm getting the following error

ERRO[0000] TypeError: Cannot read property 'split' of undefined or null
        at value (webpack://k6-jslib-aws/./src/internal/signature.ts:404:37(12))
        at value (webpack://k6-jslib-aws/./src/internal/signature.ts:300:40(32))
        at value (webpack://k6-jslib-aws/./src/internal/signature.ts:146:40(213))
        at file:///.../k6-script.js:207:2(53)  executor=per-vu-iterations scenario=default source=stacktrace

I'm also able to get the same error if I pass an empty object to the sign method with jslib 0.7.2:

	const signedRequest = signer.sign(
		{
			method: 'POST',
			protocol: 'https',
			hostname: environment.PUBLISHER_API_ENDPOINT_2_0,
			headers: headers,
			applyChecksum: true,
		},
                {}
	)

@oleiade
Copy link
Member

oleiade commented Jun 7, 2023

I think this might be caused by the fact that you omitted the path option of the object sign takes as its first argument. If you add a '/' or empty string as its value, does that address your issue?

@rtim75
Copy link

rtim75 commented Jun 7, 2023

yes, now it works. Thanks a lot

@oleiade
Copy link
Member

oleiade commented Jun 26, 2023

Glad to hear it @rtim75 🙇🏻

@oleiade oleiade closed this as completed Jun 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants