Changes touching this path
- the symptom stops leading: a transport failure names its request and says whether to retry (#966)
A first `loot clone` of the production relay failed with, in full, `loot: http:
error decoding response body`, and the identical command succeeded immediately
afterwards. That message names no request, no URL and no remedy — and it reads
as a CODEC defect, so the reasonable next move is to suspect a format skew and
go check /info. Dead end: the response had simply stopped. Same class as #914
and #921, a message that sends the reader where the bug is not.
Every `.send()` and `.bytes()` in loot-net mapped its error through a bare
`e.to_string()`, so this was not one bad message but the absence of one
everywhere. They now go through `transport_failed`, the sibling of the existing
`relay_rejected` (which is for a response that DID arrive and said no).
Three cases, because they have three remedies: unreachable (check the URL, and
do NOT retry — a wrong URL does not heal by repetition), timed out, and cut
short. The cut-short text names the interruption rather than the decode, says
re-running is the fix, says why that is safe (stow is idempotent and the
pull-side verbs negotiate from what the caller holds, so a retry resumes rather
than duplicates), and says that a repeat at the same point is the report-worthy
case — which turns a retry into evidence instead of superstition.
The underlying error survives verbatim at the end. Demoted, never hidden: it
just stops being read as the diagnosis.
⚠ The classification is split into a pure `transport_text` over a `Transport`
enum because a reqwest::Error cannot be constructed by hand, and a message whose
whole job is to send the reader to the right place is exactly the thing that
should not ship untested. Three tests, incl. one over the whole enum so a new
variant cannot quietly stop naming its request.
The eight remaining `NetError::Http(e.to_string())` sites are left alone on
purpose: they parse wire bytes already in hand, so they really are decode
errors.
Proven on the real path: a clone against a dead port now reports `pull failed
against http://127.0.0.1:59999/negotiate: could not reach it (...)` and points
at `loot remote info`.
086fb775 · dbf3dbe6…
Renames are not followed. loot's tree maps a path to an address, so a rename is a delete and an add. This list is the history of the name, not of the bytes.