Description
Checkboxes for prior research
- I've gone through Developer Guide and API reference
- I've checked AWS Forums and StackOverflow.
- I've searched for previous similar issues and didn't find any solution.
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.