Description
Expected Behaviour
When I use the Function Wrapper pattern with the makeFunctionIdempotent
function, the dataKeywordArgument
should be used to determine which of the arguments of my wrapped function to use for the data payload logged in the idempotency persistence mechanism.
With this setup, I should be able to send a payload to my function with any JSON structure and have the idempotency mechanism run successfully.
Current Behaviour
When I send a payload that does not include a property in the root of the input that matches dataKeywordArgument
, I get an error:
{
"errorType": "Error",
"errorMessage": "Failed to save record in progress. This error was caused by: The \"data\" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined.",
"cause": {
"errorType": "TypeError",
"errorMessage": "The \"data\" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined",
"code": "ERR_INVALID_ARG_TYPE",
"stack": [
"TypeError [ERR_INVALID_ARG_TYPE]: The \"data\" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined",
" at __node_internal_captureLargerStackTrace (node:internal/errors:490:5)",
" at new NodeError (node:internal/errors:399:5)",
" at Hash.update (node:internal/crypto/hash:109:11)",
" at lC.generateHash (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/persistence/BasePersistenceLayer.ts:204:10)",
" at lC.getHashedIdempotencyKey (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/persistence/BasePersistenceLayer.ts:259:49)",
" at lC.saveInProgress (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/persistence/BasePersistenceLayer.ts:132:28)",
" at io.processIdempotency (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/IdempotencyHandler.ts:145:35)",
" at io.handle (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/IdempotencyHandler.ts:115:27)",
" at u (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/makeFunctionIdempotent.ts:81:31)",
" at Runtime.lAe (/private/var/folders/4x/83k8wgzx2nj37bdnmj078nccln0f93/T/tmpg2h0cneq/app.ts:45:4)",
" at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1086:29)"
]
},
"stack": [
"Error: Failed to save record in progress. This error was caused by: The \"data\" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined.",
" at io.processIdempotency (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/IdempotencyHandler.ts:158:15)",
" at io.handle (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/IdempotencyHandler.ts:115:16)"
]
}
Code snippet
Lambda handler function initialized by sam init
using Hello World template, TypeScript
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import { IdempotencyConfig, makeFunctionIdempotent } from '@aws-lambda-powertools/idempotency';
import { DynamoDBPersistenceLayer } from '@aws-lambda-powertools/idempotency/dynamodb';
const IDEMPOTENCY_TABLE_NAME = process.env['IDEMPOTENCY_TABLE_NAME'] as string;
const persistenceStore = new DynamoDBPersistenceLayer({
tableName: IDEMPOTENCY_TABLE_NAME,
});
const processingFunction = async (payload: Record<string, APIGatewayProxyEvent>): Promise<APIGatewayProxyResult> => {
// your code goes here here
console.log('processingFunction(request).', payload);
try {
return {
statusCode: 200,
body: JSON.stringify({
message: 'tire kick created',
}),
};
} catch (err) {
console.log(err);
return {
statusCode: 500,
body: JSON.stringify({
message: 'some error happened',
}),
};
}
};
export const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
console.log('have request in handler:', event);
const result = makeFunctionIdempotent(processingFunction, {
persistenceStore,
dataKeywordArgument: 'payload',
})(event);
return result;
};
Invoke that works
Notice property that matches dataKeywordArgument
in sample
sam remote invoke --event '{"payload":"abc124"}'
Invoke that fails
sam remote invoke --event '{"something_else":"thing"}'
Steps to Reproduce
- In this environment: Latest build of powertools that includes the idempotency utility, Lambda runtime nodejs 18. No other dependencies. Set
dataKeywordArgument
to"payload"
. Lambda initialized withsam init
using TypeScript Hello World template. - When I issue a
sam remote invoke
or use the Lambda test console to send a invoke payload that does not include a property named"payload"
, I get an Error. - When I issue a
sam remote invoke
or use the Lambda test console to send an invoke payload that includes a property named"payload"
in the root of the JSON, it works.
Error: Failed to save record in progress. This error was caused by: The \"data\" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined.
Possible Solution
No response
Powertools for AWS Lambda (TypeScript) version
latest
AWS Lambda function runtime
18.x
Packaging format used
npm
Execution logs
For this log, `dataKeywordArgument` is set to `"payload"`
# Failure
INIT_START Runtime Version: nodejs:18.v8 Runtime Version ARN: arn:aws:lambda:us-east-2::runtime:2755dc322c8dbb64760145d6403d14432af527bf4dd3cf03713aae10e0f8b552
START RequestId: e3e527fa-472a-4ee1-a709-699dda02ea77 Version: $LATEST
2023-07-03T17:43:16.560Z e3e527fa-472a-4ee1-a709-699dda02ea77 INFO have request in handler: {
transaction_id: 'eee',
resource: '/tire-kicks',
path: '/tire-kicks',
httpMethod: 'PUT',
headers: {
Accept: '*/*',
'CloudFront-Forwarded-Proto': 'https',
'CloudFront-Is-Desktop-Viewer': 'true',
'CloudFront-Is-Mobile-Viewer': 'false',
'CloudFront-Is-SmartTV-Viewer': 'false',
'CloudFront-Is-Tablet-Viewer': 'false',
'CloudFront-Viewer-ASN': '7922',
'CloudFront-Viewer-Country': 'US',
'content-type': 'application/x-www-form-urlencoded',
Host: '98whvcov2m.execute-api.us-east-2.amazonaws.com',
transaction_id: '123',
'User-Agent': 'curl/7.88.1',
Via: '2.0 e807928bf10df259d5d9aa45c69572c8.cloudfront.net (CloudFront)',
'X-Amz-Cf-Id': 'Bly3yGg3y0hIdLl_cCWVcbZtahuyjNPZPA_zU_YliYCqw82IOhhQ_Q==',
'X-Amzn-Trace-Id': 'Root=1-64a2ff98-210a43b91f2d5c8b0a2d3a3d',
'X-Forwarded-For': '68.48.152.62, 15.158.47.105',
'X-Forwarded-Port': '443',
'X-Forwarded-Proto': 'https'
},
multiValueHeaders: {
Accept: [ '*/*' ],
'CloudFront-Forwarded-Proto': [ 'https' ],
'CloudFront-Is-Desktop-Viewer': [ 'true' ],
'CloudFront-Is-Mobile-Viewer': [ 'false' ],
'CloudFront-Is-SmartTV-Viewer': [ 'false' ],
'CloudFront-Is-Tablet-Viewer': [ 'false' ],
'CloudFront-Viewer-ASN': [ '7922' ],
'CloudFront-Viewer-Country': [ 'US' ],
'content-type': [ 'application/x-www-form-urlencoded' ],
Host: [ '98whvcov2m.execute-api.us-east-2.amazonaws.com' ],
transaction_id: [ '123' ],
'User-Agent': [ 'curl/7.88.1' ],
Via: [
'2.0 e807928bf10df259d5d9aa45c69572c8.cloudfront.net (CloudFront)'
],
'X-Amz-Cf-Id': [ 'Bly3yGg3y0hIdLl_cCWVcbZtahuyjNPZPA_zU_YliYCqw82IOhhQ_Q==' ],
'X-Amzn-Trace-Id': [ 'Root=1-64a2ff98-210a43b91f2d5c8b0a2d3a3d' ],
'X-Forwarded-For': [ '68.48.152.62, 15.158.47.105' ],
'X-Forwarded-Port': [ '443' ],
'X-Forwarded-Proto': [ 'https' ]
},
queryStringParameters: null,
multiValueQueryStringParameters: null,
pathParameters: null,
stageVariables: null,
requestContext: {
resourceId: 'ox2bhw',
resourcePath: '/tire-kicks',
httpMethod: 'PUT',
extendedRequestId: 'Hfzf7H9ViYcF3jA=',
requestTime: '03/Jul/2023:17:04:24 +0000',
path: '/Prod/tire-kicks',
accountId: '498170313562',
protocol: 'HTTP/1.1',
stage: 'Prod',
domainPrefix: '98whvcov2m',
requestTimeEpoch: 1688403864837,
requestId: '53bd769a-b1e4-4a74-84fa-364555b34d11',
identity: {
cognitoIdentityPoolId: null,
accountId: null,
cognitoIdentityId: null,
caller: null,
sourceIp: '68.48.152.62',
principalOrgId: null,
accessKey: null,
cognitoAuthenticationType: null,
cognitoAuthenticationProvider: null,
userArn: null,
userAgent: 'curl/7.88.1',
user: null
},
domainName: '98whvcov2m.execute-api.us-east-2.amazonaws.com',
apiId: '98whvcov2m'
},
body: '{"transactionId":"10a"}',
isBase64Encoded: false
}
2023-07-03T17:43:16.579Z e3e527fa-472a-4ee1-a709-699dda02ea77 WARN No value found for idempotency_key. jmespath:
2023-07-03T17:43:22.159Z e3e527fa-472a-4ee1-a709-699dda02ea77 ERROR Invoke Error
{
"errorType": "Error",
"errorMessage": "Failed to save record in progress. This error was caused by: The \"data\" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined.",
"cause": {
"errorType": "TypeError",
"errorMessage": "The \"data\" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined",
"code": "ERR_INVALID_ARG_TYPE",
"stack": [
"TypeError [ERR_INVALID_ARG_TYPE]: The \"data\" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined",
" at __node_internal_captureLargerStackTrace (node:internal/errors:490:5)",
" at new NodeError (node:internal/errors:399:5)",
" at Hash.update (node:internal/crypto/hash:109:11)",
" at lC.generateHash (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/persistence/BasePersistenceLayer.ts:204:10)",
" at lC.getHashedIdempotencyKey (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/persistence/BasePersistenceLayer.ts:259:49)",
" at lC.saveInProgress (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/persistence/BasePersistenceLayer.ts:132:28)",
" at io.processIdempotency (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/IdempotencyHandler.ts:145:35)",
" at io.handle (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/IdempotencyHandler.ts:115:27)",
" at u (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/makeFunctionIdempotent.ts:81:31)",
" at Runtime.lAe (/private/var/folders/4x/83k8wgzx2nj37bdnmj078nccln0f93/T/tmpg2h0cneq/app.ts:45:4)",
" at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1086:29)"
]
},
"stack": [
"Error: Failed to save record in progress. This error was caused by: The \"data\" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined.",
" at io.processIdempotency (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/IdempotencyHandler.ts:158:15)",
" at io.handle (/deps/f68a7c30-4824-4150-bbd4-4456da07f1f4/node_modules/@aws-lambda-powertools/idempotency/src/IdempotencyHandler.ts:115:16)"
]
}
END RequestId: e3e527fa-472a-4ee1-a709-699dda02ea77
Success
REPORT RequestId: e3e527fa-472a-4ee1-a709-699dda02ea77 Duration: 5664.42 ms Billed Duration: 5665 ms Memory Size: 128 MB Max Memory Used: 128 MB Init Duration: 395.56 ms
XRAY TraceId: 1-64a308b4-0e12a3155fe94234496bc4df SegmentId: 5339526d7ed02274 Sampled: true
START RequestId: fe90db53-cee2-4d46-ae9e-2f8eaea8d690 Version: $LATEST
2023-07-03T17:43:38.767Z fe90db53-cee2-4d46-ae9e-2f8eaea8d690 INFO have request in handler: {
payload: 'eee',
resource: '/tire-kicks',
path: '/tire-kicks',
httpMethod: 'PUT',
headers: {
Accept: '*/*',
'CloudFront-Forwarded-Proto': 'https',
'CloudFront-Is-Desktop-Viewer': 'true',
'CloudFront-Is-Mobile-Viewer': 'false',
'CloudFront-Is-SmartTV-Viewer': 'false',
'CloudFront-Is-Tablet-Viewer': 'false',
'CloudFront-Viewer-ASN': '7922',
'CloudFront-Viewer-Country': 'US',
'content-type': 'application/x-www-form-urlencoded',
Host: '98whvcov2m.execute-api.us-east-2.amazonaws.com',
transaction_id: '123',
'User-Agent': 'curl/7.88.1',
Via: '2.0 e807928bf10df259d5d9aa45c69572c8.cloudfront.net (CloudFront)',
'X-Amz-Cf-Id': 'Bly3yGg3y0hIdLl_cCWVcbZtahuyjNPZPA_zU_YliYCqw82IOhhQ_Q==',
'X-Amzn-Trace-Id': 'Root=1-64a2ff98-210a43b91f2d5c8b0a2d3a3d',
'X-Forwarded-For': '68.48.152.62, 15.158.47.105',
'X-Forwarded-Port': '443',
'X-Forwarded-Proto': 'https'
},
multiValueHeaders: {
Accept: [ '*/*' ],
'CloudFront-Forwarded-Proto': [ 'https' ],
'CloudFront-Is-Desktop-Viewer': [ 'true' ],
'CloudFront-Is-Mobile-Viewer': [ 'false' ],
'CloudFront-Is-SmartTV-Viewer': [ 'false' ],
'CloudFront-Is-Tablet-Viewer': [ 'false' ],
'CloudFront-Viewer-ASN': [ '7922' ],
'CloudFront-Viewer-Country': [ 'US' ],
'content-type': [ 'application/x-www-form-urlencoded' ],
Host: [ '98whvcov2m.execute-api.us-east-2.amazonaws.com' ],
transaction_id: [ '123' ],
'User-Agent': [ 'curl/7.88.1' ],
Via: [
'2.0 e807928bf10df259d5d9aa45c69572c8.cloudfront.net (CloudFront)'
],
'X-Amz-Cf-Id': [ 'Bly3yGg3y0hIdLl_cCWVcbZtahuyjNPZPA_zU_YliYCqw82IOhhQ_Q==' ],
'X-Amzn-Trace-Id': [ 'Root=1-64a2ff98-210a43b91f2d5c8b0a2d3a3d' ],
'X-Forwarded-For': [ '68.48.152.62, 15.158.47.105' ],
'X-Forwarded-Port': [ '443' ],
'X-Forwarded-Proto': [ 'https' ]
},
queryStringParameters: null,
multiValueQueryStringParameters: null,
pathParameters: null,
stageVariables: null,
requestContext: {
resourceId: 'ox2bhw',
resourcePath: '/tire-kicks',
httpMethod: 'PUT',
extendedRequestId: 'Hfzf7H9ViYcF3jA=',
requestTime: '03/Jul/2023:17:04:24 +0000',
path: '/Prod/tire-kicks',
accountId: '498170313562',
protocol: 'HTTP/1.1',
stage: 'Prod',
domainPrefix: '98whvcov2m',
requestTimeEpoch: 1688403864837,
requestId: '53bd769a-b1e4-4a74-84fa-364555b34d11',
identity: {
cognitoIdentityPoolId: null,
accountId: null,
cognitoIdentityId: null,
caller: null,
sourceIp: '68.48.152.62',
principalOrgId: null,
accessKey: null,
cognitoAuthenticationType: null,
cognitoAuthenticationProvider: null,
userArn: null,
userAgent: 'curl/7.88.1',
user: null
},
domainName: '98whvcov2m.execute-api.us-east-2.amazonaws.com',
apiId: '98whvcov2m'
},
body: '{"transactionId":"10a"}',
isBase64Encoded: false
}
2023-07-03T17:43:38.768Z fe90db53-cee2-4d46-ae9e-2f8eaea8d690 WARN Could not determine remaining time left. Did you call registerLambdaContext on IdempotencyConfig?
END RequestId: fe90db53-cee2-4d46-ae9e-2f8eaea8d690
REPORT RequestId: fe90db53-cee2-4d46-ae9e-2f8eaea8d690 Duration: 712.45 ms Billed Duration: 713 ms Memory Size: 128 MB Max Memory Used: 128 MB
XRAY TraceId: 1-64a308ca-2c283e332802034532f10fed SegmentId: 332106327066e687 Sampled: true
Metadata
Metadata
Assignees
Labels
Type
Projects
Status