Skip to content

Commit d1d2acf

Browse files
feat(idempotency): return existing record in IdempotencyValidationError (#2059)
Co-authored-by: Andrea Amorosi <[email protected]>
1 parent 36e3e62 commit d1d2acf

File tree

3 files changed

+20
-10
lines changed

3 files changed

+20
-10
lines changed

packages/idempotency/src/errors.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,14 @@ class IdempotencyInvalidStatusError extends Error {}
3030
/**
3131
* Payload does not match stored idempotency record
3232
*/
33-
class IdempotencyValidationError extends Error {}
33+
class IdempotencyValidationError extends Error {
34+
public existingRecord?: IdempotencyRecord;
35+
36+
public constructor(message?: string, existingRecord?: IdempotencyRecord) {
37+
super(message);
38+
this.existingRecord = existingRecord;
39+
}
40+
}
3441

3542
/**
3643
* State is inconsistent across multiple requests to persistence store

packages/idempotency/src/persistence/BasePersistenceLayer.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,8 @@ abstract class BasePersistenceLayer implements BasePersistenceLayerInterface {
319319
const hashedPayload: string = this.getHashedPayload(data);
320320
if (hashedPayload !== record.payloadHash) {
321321
throw new IdempotencyValidationError(
322-
'Payload does not match stored record for this event key'
322+
'Payload does not match stored record for this event key',
323+
record
323324
);
324325
}
325326
}

packages/idempotency/tests/unit/persistence/BasePersistenceLayer.test.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -243,18 +243,20 @@ describe('Class: BasePersistenceLayer', () => {
243243
payloadValidationJmesPath: 'foo',
244244
}),
245245
});
246-
jest.spyOn(persistenceLayer, '_getRecord').mockReturnValue(
247-
new IdempotencyRecord({
248-
idempotencyKey: 'my-lambda-function#mocked-hash',
249-
status: IdempotencyRecordStatus.INPROGRESS,
250-
payloadHash: 'different-hash',
251-
})
252-
);
246+
const existingRecord = new IdempotencyRecord({
247+
idempotencyKey: 'my-lambda-function#mocked-hash',
248+
status: IdempotencyRecordStatus.INPROGRESS,
249+
payloadHash: 'different-hash',
250+
});
251+
jest
252+
.spyOn(persistenceLayer, '_getRecord')
253+
.mockReturnValue(existingRecord);
253254

254255
// Act & Assess
255256
await expect(persistenceLayer.getRecord({ foo: 'bar' })).rejects.toThrow(
256257
new IdempotencyValidationError(
257-
'Payload does not match stored record for this event key'
258+
'Payload does not match stored record for this event key',
259+
existingRecord
258260
)
259261
);
260262
});

0 commit comments

Comments
 (0)