HarperFast / HarperFast/harper
Fire-and-forget writes escape the per-request transaction (commit even when the handler throws)
- Dominant language
- JavaScript
- Stars
- 89
- Forks
- 10
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 200
Description
## Summary
Only writes that are **awaited** within an HTTP resource handler join the per-request transaction (atomic + isolated). Work spawned outside the awaited chain — `setTimeout`, `queueMicrotask`, or an un-awaited promise — runs *after* the request transaction has already committed/aborted, so it lands in its own independent immediate transaction. Consequently a fire-and-forget write **commits even if the handler later throws** and its visible (awaited) work is rolled back, producing an orphan write.
This is consistent with the ALS-scoped "commit on await-resolve" design — awaited work is correctly all-or-nothing and committed state is never corrupted — but it's an undocumented sharp edge.
## Repro
Handler issues an awaited write + a `setTimeout`/un-awaited write, then throws. The awaited write rolls back; the escaped write is committed.
Exploratory test: `integrationTests/qa-scratch/txn-escape.test.ts`.
## Suggestion
Document that writes must be **awaited** inside a handler to participate in the request transaction; fire-and-forget writes are independent and survive a handler throw. (No code change implied unless we want to detect/warn on escaped writes.)
---
_Found via the exploratory QA campaign (qa-explorer), scenario QA-032. Harper `001bf7b9c` (v5.1.0, main)._
Contributor guide
Assessment
This issue has not been assessed yet.