(aws-stepfunctions-tasks): DynamoAttributeValue.fromNumber() breaks when passed a JsonPath
See original GitHub issueDynamoAttributeValue.fromNumber()
synths incorrectly when passed a JsonPath.numberAt()
for getting a number from a step’s input.
Example:
DynamoAttributeValue.fromNumber(JsonPath.numberAt('$.viewCount')
Synths as:
{\":viewCount\":{\"N\":\"-1.888154589708819e+289\"}}
Reproduction Steps
1. Deploy ProblemStack
import { Table, AttributeType, BillingMode } from '@aws-cdk/aws-dynamodb';
import { LogGroup, RetentionDays } from '@aws-cdk/aws-logs';
import { StateMachine, Chain, StateMachineType, LogLevel, JsonPath } from '@aws-cdk/aws-stepfunctions';
import { DynamoUpdateItem, DynamoAttributeValue, DynamoReturnValues } from '@aws-cdk/aws-stepfunctions-tasks';
import { Stack, Construct, StackProps, RemovalPolicy } from '@aws-cdk/core';
export class ProblemStack extends Stack {
constructor(scope: Construct, id: string, props: StackProps = {}) {
super(scope, id, props);
const table = new Table(this, 'MyTable', {
partitionKey: { name: 'id', type: AttributeType.STRING },
billingMode: BillingMode.PAY_PER_REQUEST,
removalPolicy: RemovalPolicy.DESTROY,
});
const updateViewCount = new DynamoUpdateItem(this, 'PutVideosViewCount', {
table: table,
key: {
id: DynamoAttributeValue.fromString(JsonPath.stringAt('$.id')),
},
returnValues: DynamoReturnValues.ALL_NEW,
updateExpression: 'SET viewCount = :viewCount',
expressionAttributeValues: {
':viewCount': DynamoAttributeValue.fromNumber(JsonPath.numberAt('$.viewCount')),
},
});
const main = Chain.start(updateViewCount);
const stateMachineLogs = new LogGroup(this, 'MyStateMachineLogGroup', {
retention: RetentionDays.THREE_MONTHS,
});
new StateMachine(this, 'MyStateMachine', {
definition: main,
stateMachineType: StateMachineType.STANDARD,
tracingEnabled: true,
logs: {
destination: stateMachineLogs,
includeExecutionData: true,
level: LogLevel.ALL,
},
});
}
}
2. Insert a record into the DynamoDB table
{
"id": "foo",
"viewCount": 10
}
3. Start state machine execution with event
{
"id": "foo",
"viewCount": 1234
}
What did you expect to happen?
The template should synth to extract the number from the input and then update the record in the db.
What actually happened?
The execution fails with the error:
"ExpressionAttributeValues contains invalid value: Number overflow. Attempting to store a number with magnitude larger than supported range for key :viewCount (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: c056d945-3aa5-484e-8c64-eb75b9b9041c; Proxy: null)
This is because the template was synthed as:
\"ExpressionAttributeValues\":{\":viewCount\":{\"N\":\"-1.888154589708819e+289\"}}
Environment
- CDK CLI Version : 1.83.0
- Framework Version:
- Node.js Version: v12.19.0
- OS : Linux
- Language (Version): TypeScript Version 4.0.5
Other
This is 🐛 Bug Report
Issue Analytics
- State:
- Created 3 years ago
- Reactions:12
- Comments:10 (3 by maintainers)
Top Results From Across the Web
class DynamoAttributeValue · AWS CDK
Returns the DynamoDB attribute value. static booleanFromJsonPath(value), Sets an attribute of type Boolean from state input through Json path. static fromBinary ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Quite ugly workaround, but it works and does not require one to change the functions themselves, only the CDK code.
Using
States.Format
, it’ll “convert” the number to a string. Not happy with it but it works.@shivlaks Thank you for your help
When I change it to use
numberFromString
andstringAt
. The execution still fails but with a different error:The
TaskStateEntered
for the state is the following. As you can see,viewCount
is a number.I believe this is because the template was synthed as follows, so it’s not representing value of
N.$
as a string.: