-
Notifications
You must be signed in to change notification settings - Fork 161
Description
Use case
In my current work I'm reusing the Idempotency package to consolidate potentially many events into one final entity. The first event needs to create the entity, and following events should be updates to that existing entity. The function that has been made idempotent returns the ID of the entity that was created. When the package throws a IdempotencyValidationError
that is enough for me to trigger an update but it would also be nice to know the entity ID.
For example
try {
const createdEntityId = await createThingIdempotent(createRequest)
return createdEntityId
} catch (error) {
if (error instanceof IdempotencyValidationError) {
await handleTheUpdateCase() // example
// we don't have the entityId here to return
return -1
}
throw error
}
I have means of looking up what the entityId is by searching/listing resources, so this is not a blocker for me but having the existing record available seems like a reasonable thing to expect in this kind of workflow. If the payload failing validation is an exceptional scenario, ideally you'd want to be able to recover from it rather than fail outright. In order to recover, I expect you may want to know what data is in conflict.
Solution/User Experience
Simply exposing the IdempotencyRecord
or at least the responseData
in a similar fashion to how it is done with IdempotencyItemAlreadyExistsError
should be enough to accomplish this.
powertools-lambda-typescript/packages/idempotency/src/errors.ts
Lines 6 to 13 in f9b7e6c
class IdempotencyItemAlreadyExistsError extends Error { | |
public existingRecord?: IdempotencyRecord; | |
public constructor(message?: string, existingRecord?: IdempotencyRecord) { | |
super(message); | |
this.existingRecord = existingRecord; | |
} | |
} |
powertools-lambda-typescript/packages/idempotency/src/persistence/BasePersistenceLayer.ts
Lines 156 to 161 in f9b7e6c
if (this.getFromCache(idempotencyRecord.idempotencyKey)) { | |
throw new IdempotencyItemAlreadyExistsError( | |
`Failed to put record for already existing idempotency key: ${idempotencyRecord.idempotencyKey}`, | |
idempotencyRecord | |
); | |
} |
At the place where this error is currently thrown, the existing record is in scope and should be easy to include.
powertools-lambda-typescript/packages/idempotency/src/persistence/BasePersistenceLayer.ts
Lines 317 to 326 in f9b7e6c
private validatePayload(data: JSONValue, record: IdempotencyRecord): void { | |
if (this.payloadValidationEnabled) { | |
const hashedPayload: string = this.getHashedPayload(data); | |
if (hashedPayload !== record.payloadHash) { | |
throw new IdempotencyValidationError( | |
'Payload does not match stored record for this event key' | |
); | |
} | |
} | |
} |
Alternative solutions
No response
Acknowledgment
- This feature request meets Powertools for AWS Lambda (TypeScript) Tenets
- Should this be considered in other Powertools for AWS Lambda languages? i.e. Python, Java, and .NET
Future readers
Please react with 👍 and your use case to help us understand customer demand.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status