Skip to content

fix(fmp): treat FMP error messages on HTTP 200 as status errors - #397

Merged
benbenbang merged 4 commits into
mainfrom
fix/381-invalid-name
Sep 30, 2026
Merged

benbenbang merged 4 commits into
mainfrom
fix/381-invalid-name

Conversation

@benbenbang

@benbenbang benbenbang commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

FMP sometimes returns a success status (HTTP 200) whose body is its own error message rather than the documented payload—either a short plain-text line such as Invalid name or a JSON object whose only member is "Error Message". These responses were previously reported as decode failures, masking that the request was actually rejected by the provider.

This change detects both shapes before decoding and surfaces them as status errors carrying the 200 status code, keeping the checks size-bounded so ordinary payloads are not parsed twice. It is applied consistently across the Rust core, the Go SDK, and the Python bindings.

What changed:

  • Detect provider error bodies on HTTP 200 and report them as status errors (CategoryStatus / ErrorCategory::Status with status 200, FmpStatusError in Python) instead of decode errors, in libfmp, the Go SDK, and fmp-py.
  • Introduce a dedicated provider-message error path, splitting the internal decode-failure type into a shape mismatch versus a provider message and mapping each to the appropriate error.
  • Update error descriptions across the README, .pyi stub, and exception macro to cover success statuses carrying a provider error message.
  • Add tests covering provider messages in Rust, Go, and Python, and lengthen non-JSON fixtures so they remain genuine decode errors.
  • Document the provider's undocumented per-call row caps for the economic-indicators and treasury-rates endpoints and the Invalid name behaviour.

BREAKING CHANGE: a 200 response whose body is an FMP error message now fails as a status error with status 200 instead of a decode error—CategoryStatus in the Go SDK, ErrorCategory::Status in libfmp, and FmpStatusError in Python. Match on the status category to handle it.

Closes #381

close #381

FMP sometimes answers a success status with its own error message rather
than the documented payload: a short plain-text line such as `Invalid
name`, or a JSON object whose only member is `"Error Message"`. These
bodies were previously reported as `CategoryDecode` failures, masking the
real cause.

Detect both shapes before decoding via a bounded `isProviderMessage`
check, and report them through a new `providerMessageError` as a
`CategoryStatus` error that carries the success status the provider sent.
The size-bounded checks avoid parsing ordinary payloads twice. Docs and
tests are updated to reflect that a `Status` error can now carry status
200.

BREAKING CHANGE: a 200 response whose body is an FMP error message (a short plain-text line such as Invalid name, or a JSON object whose only member is "Error Message") now fails with CategoryStatus and Status 200 instead of CategoryDecode. Match on CategoryStatus to handle it.
FMP sometimes answers a success status with its own error message instead
of the documented payload: a short plain-text line such as `Invalid name`,
or a JSON object whose only member is `"Error Message"`. These bodies were
previously misreported as decode failures, hiding the fact that the request
itself was rejected by the provider.

Recognize both shapes before decoding, bounded by size so ordinary payloads
are not parsed twice, and surface them through a new `provider_message`
error that carries the success status code. The internal `DecodeFailure`
type becomes an enum distinguishing a shape mismatch from a provider
message, and the client maps each variant to the appropriate error.

BREAKING CHANGE: a 200 response whose body is an FMP error message (a short plain-text line such as Invalid name, or a JSON object whose only member is "Error Message") now fails with ErrorCategory::Status and status_code Some(200) instead of ErrorCategory::Decode; Python raises FmpStatusError instead of FmpDecodeError. Match on the Status category to handle it.
The provider sometimes answers with a 200 whose body is its own error
message (`Invalid name`, `{"Error Message": ...}`). Surface this as
`FmpStatusError` rather than `FmpDecodeError` in the docs and tests that
accompany the behaviour shipped in libfmp.

**Documentation updates:**
* Broadened the `FmpStatusError` description in the README, the `.pyi`
  stub, and the Rust exception macro to cover success statuses whose
  body is the provider's own error message.

**Testing improvements:**
* Added a parametrised test asserting that a 200 carrying `Invalid name`
  or an `Error Message` object raises `FmpStatusError` with a status
  category and no decode kind, never `FmpDecodeError`.
* Lengthened the non-JSON fixture bodies so they remain genuine decode
  errors and are not mistaken for short provider messages.
Record the provider's undocumented per-call row limits for the
economic-indicators and treasury-rates endpoints, which silently drop
rows beyond the cap regardless of the requested window; callers should
walk long ranges in short windows and merge the pages.

Also document that an unknown economic-indicators `name` is answered
with HTTP 200 and the plain-text body `Invalid name`, surfacing as an
`ErrorCategory::Status` error with status 200 rather than a decode
error.

close #381
@benbenbang
benbenbang enabled auto-merge (rebase) September 30, 2026 15:21
@github-actions github-actions Bot added documentation Improvements or additions to documentation enhancement New feature or request labels Sep 30, 2026
@benbenbang
benbenbang merged commit fb6a08f into main Sep 30, 2026
9 of 16 checks passed
@benbenbang
benbenbang deleted the fix/381-invalid-name branch September 30, 2026 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: economic-indicators plain-text Invalid name surfaces as a decode error

1 participant