Repository navigation
fix(fmp): treat FMP error messages on HTTP 200 as status errors - #397
Merged
Merged
Conversation
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
enabled auto-merge (rebase)
September 30, 2026 15:21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 nameor 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:
CategoryStatus/ErrorCategory::Statuswith status 200,FmpStatusErrorin Python) instead of decode errors, in libfmp, the Go SDK, and fmp-py..pyistub, and exception macro to cover success statuses carrying a provider error message.Invalid namebehaviour.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—
CategoryStatusin the Go SDK,ErrorCategory::Statusin libfmp, andFmpStatusErrorin Python. Match on the status category to handle it.Closes #381
close #381