Three failure paths the streaming rewrite introduced, all found by external
review. None existed in the buffered version: the async iterator it replaced
rejected a dead request on its own, and never opened the chunk file until it
already held the whole body.
- An already-destroyed request hung the call forever. If the client hangs up
while auth and ownership are awaiting the database, pipe() emits neither
`end` nor `error`, so the promise never settled and the write descriptor
stayed open. Checked up front now, alongside `aborted` and a `close` without
`readableEnded` for a body cut short mid-flight.
- A failed re-send destroyed the chunk it was replacing. createWriteStream
truncates on open, so re-sending an index and then failing left
receivedChunks and chunkSizes still claiming the old copy: status reported
100% and completeUpload died on ENOENT. Chunks are staged through a sibling
.part file and renamed only on success.
- Tripping the cap stopped the 413 from reaching the client. `source` is the
IncomingMessage, so destroying it destroyed the socket under the response
and the client saw a connection reset instead of the size-limit JSON. The
read is paused instead, which is all the cap needs.
Relates to issue 1403