Skip to content

fix: return error frames instead of dropping connection on store errors#22

Merged
jmccarthy merged 2 commits intostrongdm:mainfrom
pagerguild:fix/getblob-error-frame
Feb 24, 2026
Merged

fix: return error frames instead of dropping connection on store errors#22
jmccarthy merged 2 commits intostrongdm:mainfrom
pagerguild:fix/getblob-error-frame

Conversation

@tylergannon
Copy link
Contributor

Summary

GetBlob, GetHead, and PutBlob handlers used ? on store operations, which propagated errors out of handle_client() and dropped the TCP connection. This violated the protocol spec (docs/protocol.md §7) which requires a 404 ERROR frame for blob not found.

Changes

Server (Rust):

  • Changed store operation errors to flow into the response match so the error-frame builder (map_error + encode_error) handles them properly

Go Client:

  • GetBlob implementation for Client and ReconnectingClient
  • ErrBlobNotFound sentinel error
  • Unit tests with mock TCP server (fs_test.go)
  • cxdb-blob-verify CLI tool for live server validation
  • get_blob protocol fixture

Testing

  • Unit tests verify error wrapping, response parsing, and round-trip behavior
  • cxdb-blob-verify tool includes a "connection survives not-found" test that confirms the fix works end-to-end

GetBlob, GetHead, and PutBlob handlers used ? on store operations,
which propagated errors out of handle_client() and dropped the TCP
connection. This violated the protocol spec (docs/protocol.md s7)
which requires a 404 ERROR frame for blob not found.

Changed store operation errors to flow into the response match so
the error-frame builder (map_error + encode_error) handles them.

Go client additions:
- GetBlob implementation (Client + ReconnectingClient)
- ErrBlobNotFound sentinel error
- Unit tests with mock TCP server (fs_test.go)
- cxdb-blob-verify CLI tool for live server validation
- get_blob protocol fixture
Adds a boolean Synthetic field to UserInput for marking programmatically
injected messages (e.g., from navigators or orchestrators) vs direct human
input. UIs may render synthetic inputs differently (dimmed, different icon).

This is a simpler alternative to a separate SteeringMessage type - all
steering/injection use cases can use UserInput{Synthetic: true}.
@jmccarthy jmccarthy merged commit 300fadb into strongdm:main Feb 24, 2026
10 of 11 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.

2 participants