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

DynamoDBDocumentClient throws on marshalling of class instances where class includes bound functions or arrow functions, despite convertClassInstanceToMap = true #5686

Closed
3 tasks done
firekart opened this issue Jan 16, 2024 · 3 comments
Assignees
Labels
bug This issue is a bug. p2 This is a standard priority issue queued This issues is on the AWS team's backlog workaround-available This issue has a work around available.

Comments

@firekart
Copy link

firekart commented Jan 16, 2024

Checkboxes for prior research

Describe the bug

[ Edited to include bound functions ]
An error is now thrown If bound or arrow functions are included as part of a class, when an instance of that class is used in PutCommand, BatchWriteCommand, DeleteCommand, etc. Example of error 'Unsupported type passed: () => this.props. Pass options.convertClassInstanceToMap=true to marshall typeof object as map attribute.'

SDK version number

@aws-sdk/lib-dynamodb@3.490.0

Which JavaScript Runtime is this issue in?

Node.js

Details of the browser/Node.js/ReactNative version

v18.17.1

Reproduction Steps

import { DynamoDBClient, DynamoDBClientConfig, } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, PutCommand, TranslateConfig } from "@aws-sdk/lib-dynamodb";

const datastoreParams: DynamoDBClientConfig = {
    region: 'ap-southeast-2'
};

const marshallOptions: TranslateConfig[ 'marshallOptions' ] = {
    convertEmptyValues: false,
    removeUndefinedValues: true,
    convertClassInstanceToMap: true,
};

const unmarshallOptions: TranslateConfig[ 'unmarshallOptions' ] = {
    wrapNumbers: false,
};

const translateConfig: TranslateConfig = { marshallOptions, unmarshallOptions };
const dynamoDb = new DynamoDBClient(datastoreParams);
const dynamoDbConfig = { client: dynamoDb };

const docClient = DynamoDBDocumentClient.from(dynamoDbConfig.client, translateConfig);

/** a function to be bound to X */
function boundGetProps( this: X ) {
    return this.props
}

/** a dummy class that conforms to our schema */
class X {
    constructor({ sk, pk, ...others }: Record<string, any>) {
        this.sk = sk
        this.pk = pk
        this.props = others
        /** binding this function will cause  Unsupported type passed error, despite convertClassInstanceToMap: true  */
        this.boundGetProps = boundGetProps.bind( this )
        /* commenting out this binding and the boundGetProps below will give the expected */

    }
    sk: string
    pk: string
    props: Record<string, any>

    _position: { lat: number, lng: number} | undefined

    boundGetProps: () => Record<string, any>

    /* this arrow fn will cause Unsupported type passed error, despite convertClassInstanceToMap: true  */
    arrowGetProps = () => this.props
    /* commenting this arrow fn out give the expected */

    /** functions expressions are ok */
    normalGetProps() {
        return this.props
    }

    /** Getter Setters are OK */
    get position() {
        return this._position
    }

    set position( position:{ lat: number, lng: number} | undefined ) {
        this._position = position
    }
}


const main = async () => {
    const x = new X({ pk: 'X:1', sk: 'X:1',  })
    x.position = { lat: 10, lng: -22 }
    try {
        const putRes = await docClient.send(new PutCommand({
            TableName: 'i3012-dev-main-table',
            Item: x
        }))
        console.log('putRes', putRes)
    } catch (e: any) {
        console.log(e)
    }
}

(global as any).main = main()

Observed Behavior

Error: Unsupported type passed: () => this.props. Pass options.convertClassInstanceToMap=true to marshall typeof object as map attribute.
at convertToAttr (/Volumes/wx/code/iotv/lws/node_modules/@aws-sdk/util-dynamodb/dist-cjs/convertToAttr.js:53:11)
at marshall (/Volumes/wx/code/iotv/lws/node_modules/@aws-sdk/util-dynamodb/dist-cjs/marshall.js:6:62)
at marshallFunc (/Volumes/wx/code/iotv/lws/node_modules/@aws-sdk/lib-dynamodb/dist-cjs/commands/utils.js:64:71)
at processObj (/Volumes/wx/code/iotv/lws/node_modules/@aws-sdk/lib-dynamodb/dist-cjs/commands/utils.js:12:20)
at /Volumes/wx/code/iotv/lws/node_modules/@aws-sdk/lib-dynamodb/dist-cjs/commands/utils.js:56:32
at Array.reduce ()
at processAllKeysInObj (/Volumes/wx/code/iotv/lws/node_modules/@aws-sdk/lib-dynamodb/dist-cjs/commands/utils.js:55:32)
at processObj (/Volumes/wx/code/iotv/lws/node_modules/@aws-sdk/lib-dynamodb/dist-cjs/commands/utils.js:23:24)
at processKeysInObj (/Volumes/wx/code/iotv/lws/node_modules/@aws-sdk/lib-dynamodb/dist-cjs/commands/utils.js:44:32)
at marshallInput (/Volumes/wx/code/iotv/lws/node_modules/@aws-sdk/lib-dynamodb/dist-cjs/commands/utils.js:65:12)

Expected Behavior

putRes {
'$metadata': {
httpStatusCode: 200,
requestId: 'NM3UDHU0BFC0766O6NBHE8V6GNVV4KQNSO5AEMVJF66Q9ASUAAJG',
extendedRequestId: undefined,
cfId: undefined,
attempts: 1,
totalRetryDelay: 0
}
}

Possible Solution

No response

Additional Information/Context

This seems to be a change in behavior from recent versions of @aws-sdk/lib-dynamodb. It was picked up because of a manual change made to a Lamdba's environment variables in the aws console. Which presumably allowed lambda to relaunch with new package versions.

I am not sure if its a bug or by design, can't find any reference to it.

@firekart firekart added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Jan 16, 2024
@firekart firekart changed the title DynamoDBDocumentClient in rejects marshalling of arrow functions in class instances despite convertClassInstanceToMap = true DynamoDBDocumentClient throws on marshalling of class instances where class inludes arrow functions, despite convertClassInstanceToMap = true Jan 17, 2024
@firekart firekart changed the title DynamoDBDocumentClient throws on marshalling of class instances where class inludes arrow functions, despite convertClassInstanceToMap = true DynamoDBDocumentClient throws on marshalling of class instances where class includes bound functions or arrow functions, despite convertClassInstanceToMap = true Jan 17, 2024
@kuhe kuhe added p2 This is a standard priority issue and removed needs-triage This issue or PR still needs to be triaged. labels Jan 18, 2024
@kuhe kuhe self-assigned this Jan 18, 2024
@kuhe kuhe added the queued This issues is on the AWS team's backlog label Jan 18, 2024
@kuhe
Copy link
Contributor

kuhe commented Jan 19, 2024

We are working on a fix, as linked in the PR. In the meantime, please convert your JS object to a data object by filtering out functions before passing to the SDK.

@kuhe kuhe added the workaround-available This issue has a work around available. label Jan 19, 2024
@siddsriv
Copy link
Contributor

A fix (linked in the PR above) has been merged. Closing this issue, please inform us if something comes up.

Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug This issue is a bug. p2 This is a standard priority issue queued This issues is on the AWS team's backlog workaround-available This issue has a work around available.
Projects
None yet
Development

No branches or pull requests

3 participants