-
Notifications
You must be signed in to change notification settings - Fork 153
Bug: Idempotency middleware doesn't work for functions without return value #2987
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
Comments
@dreamorosi added support for functions with no return value in #2521 Hope this helps with the triage! |
Hi @wassil, thank you for opening the issue and reporting the bug. I was able to reproduce the behavior you describe and confirm that when the handler function doesn't return a value, the Middy.js middleware runs twice. ![]() We'll look into fixing the issue. |
I have spent some time looking at the implementation (thanks for the exhaustive report!) and unfortunately I think we can't do anything unless Middy.js itself supports this use case. I have opened an issue on their repo (middyjs/middy#1236) and will be waiting to hear from the maintainer(s) on whether this is something that can be supported or not. I'll wait for a couple of days, after which I'll add a banner to our docs to explain the limitation and suggest customers to use other Idempotency methods (i.e. function wrapper or class method decorator) if their use case can return |
Yeah, there is no nice clean solution and I don't think there is a difference between I was considering writing my own idempotency middleware using this package. We also have a batch processing use-case where I want to mark individual messages as processed.
But it feels like a hack to be honest. |
We have something similar as a feature request that is already in python implementation #2887 but this is mostly for "Processing completed" case. |
Middy documentation is now updated. |
We haven't and in general we try to keep our public API tidy & focused, although we are open to proposals in this sense. For this specific case, I'd like to propose the following actions:
Specifically, even when using other Middy.js middlewares, you can wrap your handler like this: import middy from '@middy/core';
import { Logger } from '@aws-lambda-powertools/logger';
import { injectLambdaContext } from '@aws-lambda-powertools/logger/middleware';
import { makeIdempotent } from '@aws-lambda-powertools/idempotency';
import { DynamoDBPersistenceLayer } from '@aws-lambda-powertools/idempotency/dynamodb';
const logger = new Logger();
const persistenceStore = new DynamoDBPersistenceLayer({
tableName: process.env.IDEMPOTENCY_TABLE_NAME as string,
});
export const handler = middy(
makeIdempotent(
async () => {
logger.info('stuff');
},
{ persistenceStore }
)
).use(injectLambdaContext(logger)); In this example I am using another Powertools for AWS middleware (from Logger), but using the The difference however is that using this method your function is considered idempotent even if its return value is I will open a PR to update the docs shortly. |
This issue is now closed. Please be mindful that future comments are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so. |
This is now released under v2.8.0 version! |
Expected Behavior
When using the
makeHandlerIdempotent
middleware with a handler function that has no return value(undefined
), the middleware should only call the handler once.Current Behavior
The handler is called multiple times for the same event, even though the idempotency record exists in Dynamo.
The issue is that the package returns the stored return value from previous run from the middleware.
Here: https://github.com/aws-powertools/powertools-lambda-typescript/blob/main/packages/idempotency/src/IdempotencyHandler.ts#L243
And here: https://github.com/aws-powertools/powertools-lambda-typescript/blob/main/packages/idempotency/src/middleware/makeHandlerIdempotent.ts#L140
If the value returned from middleware is truthy, it causes middy to perform an early return(https://middy.js.org/docs/intro/early-interrupt/).
This works for handler that have a return value, but doesn't work when the return value is
undefined
- middy doesn't early return and the handler code is executed again.Code snippet
export handler = middy().use(makeHandlerIdempotent(...)).handler(() => console.log("stuff"))
Steps to Reproduce
Use the code snippet, call the lambda multiple times with the same event
Possible Solution
In order to early return, a truthy value has to be returned from the middleware.
This kind of sucks, because the first time a lambda runs, it returns
undefined
and we'd have to return something else when idempotency key is present.In our use case, the return value doesn't matter, but I'm not sure what would make sense as a generic solution.
Powertools for AWS Lambda (TypeScript) version
latest
AWS Lambda function runtime
20.x
Packaging format used
npm
Execution logs
No response
The text was updated successfully, but these errors were encountered: