Skip to content

fix(backend): release idempotency locks reliably on internal errors - #1199

Merged
FaveTeamz merged 2 commits into
FaveTeamz:mainfrom
chukwunazannakenyi-netizen:fix/1013-idempotency-lock-release
Oct 24, 2026
Merged

FaveTeamz merged 2 commits into
FaveTeamz:mainfrom
chukwunazannakenyi-netizen:fix/1013-idempotency-lock-release

Conversation

@chukwunazannakenyi-netizen

Copy link
Copy Markdown
Contributor

What was implemented

Adds src/middleware/idempotency.ts — a Redis-backed idempotency middleware that prevents duplicate processing of mutating HTTP requests (POST, PUT, PATCH, DELETE).

Core fix (#1013)

The in-flight lock key (idem:lock:<key>) is now deleted inside a try...finally block. Previously, if a downstream route handler threw an unexpected error, the lock would persist in Redis until its TTL expired — blocking clients from safely retrying. With the finally block, the lock is always released immediately, regardless of whether the handler succeeded or threw.

Behaviour overview

Scenario Response
Missing Idempotency-Key header on mutating request 400 missing_idempotency_key
Completed result already cached Replay with original status/body + X-Idempotency-Replayed: true
Duplicate in-flight request 409 duplicate_request
Handler succeeds Result persisted for 24 h under idem:result:<key>
Handler throws (any error) Lock deleted immediately in finally block — client can retry

Files changed

  • src/middleware/idempotency.ts — new middleware (try…finally lock cleanup)
  • src/app.ts — wires idempotencyMiddleware in after audit middleware

Closes #1013

Adds src/middleware/idempotency.ts — a Redis-backed idempotency
middleware that prevents duplicate processing of mutating requests.

The core fix for FaveTeamz#1013: the in-flight lock key (idem:lock:<key>) is now
deleted inside a try...finally block, so any unhandled exception thrown
by a downstream route handler triggers immediate lock release instead of
letting the key persist until TTL expiry. This allows clients to retry
safely after an unexpected server error.

Key behaviours implemented:
- Missing Idempotency-Key on mutating requests → 400
- Completed result found in Redis → 409-free replay with original status/body
- Duplicate in-flight request → 409 duplicate_request
- Successful response persisted for 24 h under idem:result:<key>
- Lock always released in finally block (fixes FaveTeamz#1013)

Wires idempotencyMiddleware into app.ts after the audit middleware so it
applies globally to all POST/PUT/PATCH/DELETE routes.

Closes FaveTeamz#1013
@FaveTeamz
FaveTeamz merged commit 7bd062f into FaveTeamz:main Oct 24, 2026
15 of 43 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(backend): Release idempotency locks reliably on internal errors

2 participants