Skip to content

ws: define bounded diagnostics for parser-failure frames #93

Description

@qiuqiuaiweb3

Summary

When a full WebSocket text frame fails to parse, the shared connection logs the complete
raw frame at WARN:

tracing::warn!(%text, error = %e, "Failed to parse WebSocket message");

This is separate from the opt-in pre-parse raw TRACE event. A deployment that enables
WARN for the SDK can therefore record the complete contents of malformed inbound
frames without enabling raw TRACE logging.

Reproduction

I tested crates.io polymarket_client_sdk_v2 0.7.0 and current main
222143d321eba97d5711a848265eb9aab3bc7ff4 with a loopback WebSocket server and fixed
synthetic values only.

The server waited for the client's real CLOB market subscription, then sent:

  1. an otherwise valid interested book frame whose timestamp was changed to
    "not-an-i64" and whose synthetic hash contained begin/middle/end markers around
    4,096 A and 4,096 B characters; and
  2. a valid book frame.

The malformed compact JSON frame was 8,574 bytes. With a WARN-only filter, each run
observed exactly one Failed to parse WebSocket message event containing error=, the
byte-for-byte complete malformed frame, and all sentinel markers. No
Received WebSocket text message TRACE event was enabled. The valid follow-up still
arrived as a typed BookUpdate on the same connection.

An explicit TRACE control observed both raw text frames, as expected. A build without
the tracing feature also dropped the malformed frame and delivered the valid
follow-up, confirming that receive behavior is independent of the logging feature.

Baseline WARN/TRACE observation Candidate bounded-WARN check Non-tracing control
crates.io 0.7.0 3/3: 3 passed, 1 ignored 3/3: RED, exit 101 3/3 passed
main 222143d 3/3: 3 passed, 1 ignored 3/3: RED, exit 101 3/3 passed

The source path is
src/ws/connection.rs.
The SDK applies no truncation or redaction before passing %text to the WARN event.
The 8,574-byte observation establishes this SDK-layer behavior for the tested frame; it
does not claim that every downstream subscriber or log backend is itself unbounded.

Related history

The archived predecessor's
PR #26 review feedback
already identified full raw-text logging and suggested retaining message_len instead.
That thread is resolved/outdated, the PR merged, and current v2 source still logs
%text, so there is no active v2 tracker or applied fix.

Current #85 is related but
distinct: it asks how full-frame parser failures should reach subscription consumers.
This report is only about what the WARN event contains and does not ask to change stream
propagation or connection behavior.

The archived predecessor's
PR #212 used a complete parser
WARN to identify a real MarketResolved schema mismatch, so the current output has
demonstrated diagnostic value. That PR fixed the response model; it did not decide how
much raw frame content belongs in the default WARN.

Requested outcome

Could maintainers define a bounded default diagnostic contract for parser failures?
Options include retaining the parse error with UTF-8 byte length only, a bounded and
redacted preview, a digest, or explicitly retaining the complete frame. The first three
reduce routine log exposure and amplification, while the last preserves the diagnostic
value demonstrated by PR #212. I have not selected one in a patch because the exact
historical message_len suggestion was not adopted and the preferred tradeoff is a
maintainer decision.

This report does not claim that credentials are currently echoed by the service or that
a practical credential leak has been demonstrated. It reports deterministic synthetic
logging behavior and a defense-in-depth hardening boundary.

This report and test matrix were prepared and executed with an AI coding assistant; I
reviewed the evidence and exact Issue body before submission.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions