Skip to content

fix: bare-array endpoints lost their rows and their envelope - #2

Open
tomaszdobrowolski1 wants to merge 1 commit into
mainfrom
fix/array-endpoint-envelope
Open

fix: bare-array endpoints lost their rows and their envelope#2
tomaszdobrowolski1 wants to merge 1 commit into
mainfrom
fix/array-endpoint-envelope

Conversation

@tomaszdobrowolski1

Copy link
Copy Markdown
Contributor

Blocker from the pre-release review: on the one endpoint that returns a bare JSON array, this client lost the rows and the envelope.

What was broken

Go discarded the array silently. handle() unmarshalled into map[string]interface{} and dropped the resulting error, so callers got an empty map that looked like a successful empty result. OptionQuoteTyped then re-encoded that empty map and returned a single zero-valued quote. No error anywhere.

Java failed loudly but opaquely. handleResponse called getAsJsonObject() on every 200, which throws IllegalStateException on an array. The javadoc had been documenting a workaround - "prefer the parameterised overload" - rather than the defect.

Both predate the envelope work; the envelope rollout is what surfaced them.

The fix

*WithMetadata accessors return the rows and the envelope together. An array body has nowhere to carry an envelope, so the API sends provenance in X-Data-As-Of / X-Endpoint-Version headers - and returning the parsed body alone threw that away.

Live, unfiltered SPY: 6,407 quotes with provenance. Go previously returned 1 empty quote; Java threw.

A malformed or absent header leaves provenance null rather than failing the call. Provenance is diagnostic - an upstream header change should never turn a good response into an error.

Scope

Deliberately narrow. Go's handle() now delegates to a new handleRaw so every status and error branch stays in one place; Java gains a private getRaw that keeps the whole response. Object-bodied endpoints are untouched in both. The untyped accessors keep their signatures - Java's now raises a FlashAlphaException naming the accessor that works, instead of an opaque cast failure.

Tests

Nine new tests across the two repos, all offline against a stub server, pinning the parts that were silently wrong:

  • the rows survive (a count of 1 means the old path is back)
  • the envelope parses out of the headers, including nulls staying null
  • a malformed header does not fail the call
  • the single-object shape a filtered call returns still decodes
  • Java's untyped accessor gives an actionable message

Suites green: Go clean, Java 193 run / 0 failures. Verified live on both.

Version 1.4.0.

Both clients decoded every response into a shape that cannot hold a JSON
array, so the one endpoint that returns an array was broken in different
ways in each language - and in both, provenance was unreachable.

Go discarded the array silently. handle() unmarshalled into
map[string]interface{} and dropped the resulting error, so callers got an
empty map that looked like a successful empty result. OptionQuoteTyped
then re-encoded that empty map and returned a single zero-valued quote.
An unfiltered live SPY call now returns 6,407 quotes; it previously
returned one empty one, with no error anywhere.

Java failed loudly but opaquely. handleResponse called getAsJsonObject()
on every 200, which throws IllegalStateException on an array. The javadoc
had been documenting a workaround - "prefer the parameterised overload" -
rather than the defect. The untyped accessor now raises a
FlashAlphaException naming the accessor that works.

Both gain a *WithMetadata accessor. An array body has nowhere to carry an
envelope, so the API sends provenance in the X-Data-As-Of and
X-Endpoint-Version headers, and returning the parsed body alone threw
that away. OptionQuoteWithMetadata / optionQuoteWithMetadata return the
rows and the envelope together, which is the only way to reach provenance
for such an endpoint.

A malformed or absent header leaves the provenance nil rather than
failing the call. Provenance is diagnostic, and an upstream header change
should never turn a good response into an error.

The refactors are deliberately narrow: Go's handle() now delegates to a
new handleRaw so every status and error branch stays in one place, and
Java gains a private getRaw that keeps the whole response. Object-bodied
endpoints are untouched in both.

Nine tests, all offline against a stub server, pin the parts that were
silently wrong: the rows survive, the envelope parses out of the headers,
a bad header does not fail the call, the single-object shape a filtered
call returns still decodes, and Java's untyped accessor gives an
actionable message. Verified live as well - 6,407 quotes with the
envelope present on both.

Go 1.4.0, Java 1.4.0.
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