Skip to content

fix(protocol): return only the error body when a Block2 transfer fails - #61

Merged
QuiteYellow merged 1 commit into
mainfrom
fix/block2-error-payload
Aug 23, 2026
Merged

fix(protocol): return only the error body when a Block2 transfer fails#61
QuiteYellow merged 1 commit into
mainfrom
fix/block2-error-payload

Conversation

@QuiteYellow

Copy link
Copy Markdown
Owner

Follow-up to #36, on one contract detail I raised in review and then took myself.

Block2Accumulator.add_response extended the accumulated representation with a non-success response's body before completing. A 4.xx or 5.xx arriving mid-transfer produced one buffer holding assembled blocks followed by a diagnostic in the server's own format, and get() returns (code, payload) with no boundary marker between them, so the caller had no way to split it.

The error body now replaces the partial representation.

Nothing observed the old behaviour

Every get() consumer gates on the code before touching the payload: bridge.py:253, :486 and :516 all check for 2.05 first. Once the code is not 2.xx the accumulated bytes had no reader.

The first-block case is unchanged

Where the error arrives before any block, #36 already returned the diagnostic body where the pre-#36 path returned an empty buffer. That was an improvement and it stays. This change makes it the behaviour in every case.

Bounds

The payload bound moves from the combined length to the error body's own, since the buffer now only ever holds one or the other. An error body that fits is accepted however many bytes arrived before it; an oversized one still raises BlockwiseError.

Tests

Two tests pinned the old contract and both are updated, one at the accumulator and one driving it end to end through get():

  • test_mid_transfer_error_replaces_the_partial_representation
  • test_get_returns_only_the_error_body_when_a_transfer_fails_mid_way

Two added:

403 pass. Ruff clean on all three touched files.

Hardware

Not separately validated. #36 itself ran on the reference bridge against one dryer and one oven across a container recreate, and this path needs a mid-transfer 4.xx from the appliance to fire, which neither device produced during that run.

Block2Accumulator.add_response extended the accumulated representation
with a non-success response's body before completing, so a 4.xx or 5.xx
arriving mid-transfer produced one buffer holding assembled blocks
followed by a diagnostic in the server's own format. get() returns
(code, payload) with no boundary marker between the two, leaving the
caller no way to split them.

The error body now replaces the partial representation. Nothing observed
the old behaviour: every caller gates on 2.05 before decoding, so the
accumulated bytes had no reader once the code was not 2.xx.

Where the error arrives before any block, this is unchanged from #36,
which already returned the diagnostic where the pre-#36 path returned an
empty buffer. This makes that the behaviour in every case.

The payload bound moves with it, from the combined length to the error
body's own, since the buffer now only ever holds one or the other.
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.

1 participant