Skip to content

fix(sdk): wrap member decode errors with field context - #402

Merged
benbenbang merged 1 commit into
mainfrom
fix/go_binding
Oct 1, 2026
Merged

benbenbang merged 1 commit into
mainfrom
fix/go_binding

Conversation

@benbenbang

Copy link
Copy Markdown
Member

Replace bare error returns in the congressional net worth JSON
unmarshaling with calls to memberDecodeError, attaching the type name,
field name, and raw value to each failure. This produces clearer,
actionable error messages when decoding CongressionalNetWorthRange and
CongressionalMemberNetWorth fields fails.

Replace bare error returns in the congressional net worth JSON
unmarshaling with calls to `memberDecodeError`, attaching the type name,
field name, and raw value to each failure. This produces clearer,
actionable error messages when decoding `CongressionalNetWorthRange` and
`CongressionalMemberNetWorth` fields fails.
@benbenbang
benbenbang enabled auto-merge (squash) October 1, 2026 03:46
@benbenbang
benbenbang merged commit 2356304 into main Oct 1, 2026
9 checks passed
@benbenbang
benbenbang deleted the fix/go_binding branch October 1, 2026 04:01
ptah-bw-technical-app Bot added a commit that referenced this pull request Oct 2, 2026
## [1.2.0](1.1.0...1.2.0) (2026-10-02)

### ⚠ BREAKING CHANGES

* **company:** CompanyProfile.isin, country, change and change_percentage are now optional in Rust, Python and Go, affecting both company.profile and bulk company_profiles.
* **bulk:** every numeric member of BulkCashFlowStatement, BulkCashFlowStatementGrowth and BulkEodBar is now optional in Rust, Python and Go.
* **bulk:** every numeric member of BulkBalanceSheetStatement and BulkBalanceSheetStatementGrowth is now optional in Rust, Python and Go.
* **bulk:** every numeric member of BulkIncomeStatement and BulkIncomeStatementGrowth is now optional in Rust, Python and Go.
* **bulk:** every numeric member of BulkKeyMetricsTtm, BulkFinancialRatiosTtm and BulkEarningsSurprise is now optional in Rust, Python and Go.
* **bulk:** discounted_cash_flow_score, return_on_equity_score,
return_on_assets_score, debt_to_equity_score, price_to_earnings_score,
price_to_book_score, dcf, stock_price, reported_currency, altman_z_score,
piotroski_score, working_capital, total_assets, retained_earnings, ebit,
market_cap, total_liabilities, revenue, last_month_count,
last_month_avg_price_target, last_quarter_count,
last_quarter_avg_price_target, last_year_count, last_year_avg_price_target,
all_time_count, all_time_avg_price_target, shares_number, asset,
weight_percentage, isin, market_value, strong_buy, buy, hold, sell and
strong_sell are now Option<NumericString> (asset Option<Ticker>, isin
Option<Isin>, reported_currency Option<CurrencyCode>) in Rust,
Optional[str] in Python and *string in Go.
* **bulk:** the income-statement-bulk, income-statement-growth-bulk, balance-sheet-statement-bulk, balance-sheet-statement-growth-bulk, cash-flow-statement-bulk, cash-flow-statement-growth-bulk, and eod-bulk methods now require a text/csv response.
* **bulk:** the four bulk methods KeyMetricsTTM, FinancialRatiosTTM, StockPeers, and EarningsSurprises now require a text/csv response and no longer decode JSON.
* **bulk:** the seven snapshot bulk methods now require a text/csv response; BulkEtfHolding.last_updated_raw is renamed to last_updated and typed as Date in Rust, Python and Go.
* **responses:** CongressionalMemberNetWorth and CongressionalMemberNetWorthAggregate no longer derive Eq (their f64 amounts); compare fields instead.
* **responses:** CongressionalMemberNetWorth.value and the
CongressionalMemberNetWorthAggregate amounts changed from i64 to f64
(MarketValue). CongressionalMemberNetWorth.category, name, owner and value,
CongressionalNetWorthRange.max, CongressionalDebtDetails.date_incurred and
CongressionalMemberNetWorthAggregate.real_estate, stock,
real_estate_liabilities, business_and_self_employment, ownership_interest,
options, revolving_and_credit_lines, asset_backed_securities and
business_liabilities are now optional (Option / pointer / Optional); handle
None.
* **funds:** FundDisclosureSearchResult.entity_org_type is now optional
(Option<NumericString> / *string / Optional[str]); the provider's "NULL"
text and null decode as None, so handle None.
* **libfmp:** 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.
* **sdk/go:** 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.
* **indexes:** IndexConstituent.founded is now String (Rust) / string
(Go) / str (Python) holding the founding year(s) verbatim, e.g. "1994" or
"1902/1985"; it was a Date. Compare or parse the string instead of a date.
* **calendar:** IpoProspectus.ipo_date is now DateOrYear in Rust (match Date or Year, or use as_date/as_year), datetime.date | int in Python (a bare year is an int), and fmp.DateOrYear in Go (use .Date() / .Year()).
* **responses:** CrowdfundingOffering, RegulationDOffering, SecCompanyProfile and SecCompanySearchResult members FMP can omit are now optional (Option / pointer / Optional); handle None.
* **crypto:** CryptocurrencyListing members FMP can omit are now optional (Option / pointer / Optional); handle None.
* **responses:** NewsArticle, ExchangeHoliday, EsgDisclosure, EsgRating and CongressionalMemberProfile members FMP can omit are now optional (Option / pointer / Optional); handle None.
* **statements:** IncomeStatement, KeyMetrics, KeyMetricsTtm, FinancialScore, AsReportedFinancialStatement and FinancialEstimate members FMP can omit are now optional (Option / pointer / Optional); handle None.
* **directory:** AvailableExchange, FinancialStatementSymbol and HistoricalIndexConstituent members FMP can omit are now optional, and "" on their typed codes decodes as None (Option / pointer / Optional); handle None.
* **insider-trading:** InsiderTrade, BeneficialOwnershipAcquisition, InstitutionalHolding and HolderIndustryBreakdown members FMP can omit are now optional (Option / pointer / Optional); handle None.
* **funds:** EtfFundHolding, FundDisclosure and FundDisclosureSearchResult
members FMP can omit are now optional (Option / pointer / Optional); handle
None.
* **calendar:** DividendEvent, EarningsEvent, IpoCalendarEvent, IpoProspectus and StockSplitEvent members FMP can omit are now optional (Option / pointer / Optional); handle None.
* **search:** ExchangeVariant and CompanyScreenerResult members FMP
can omit are now optional (Option / pointer / Optional); handle None.
* **statements:** 57 BalanceSheetStatement and CashFlowStatement amounts
are now optional (Option / pointer / Optional); callers must handle None.
* **economics:** TreasuryRate tenors, EconomicIndicatorObservation.value
and six EconomicCalendarEvent members are now optional (Option / pointer
/ Optional); handle None.
* **quote:** QuoteShort price, change and volume and AftermarketTrade.tradeSize are now optional (Option / pointer / Optional); callers must handle None.
* **company:** CompanyProfile, CompanyExecutive, CompanyMarketCapitalization, CompanyNote, CompanyShareFloat, ShareFloat, ExecutiveCompensation and MergerAcquisition members FMP can omit are now optional (Option / pointer / Optional); handle None.
* **statements:** financial_reports_json now returns a single
FinancialReportJson instead of a list; drop the [0] / iteration.

* **responses:** cover null aggregate fields decoding as None ([351281b](351281b))

### 🎁 Features

* **calendar:** make omittable calendar members optional ([fefb037](fefb037))
* **codecs:** add DateOrYear for date-or-year wire fields ([0d2bac5](0d2bac5))
* **codecs:** add empty_or_null deserializer for nullable typed codes ([98a10f9](98a10f9)), closes [#368](#368)
* **company:** make provider-omittable company members optional ([370d0b4](370d0b4))
* **crates:** support single-model endpoints in generators ([3673318](3673318))
* **crypto:** make omittable CryptocurrencyListing members optional ([f69fdef](f69fdef))
* **directory:** make omittable directory and index members optional ([eefaaf8](eefaaf8))
* **economics:** make treasury tenors and calendar figures optional ([b3a7969](b3a7969)), closes [#368](#368) [#368](#368)
* **fmp-py-gen:** use ClientHandle for namespace clients ([8b6baf1](8b6baf1))
* **fmp-py:** add close and context manager support to FmpClient ([43e3944](43e3944))
* **funds:** make omittable fund members optional ([64eab5b](64eab5b))
* **gen-go:** add empty_or_null string codec for Go models ([0bb05b0](0bb05b0))
* **go-sdk:** add CloseIdleConnections to release the owned pool ([85651e9](85651e9)), closes [#371](#371)
* **insider-trading:** make FMP-omittable members optional ([9c96061](9c96061))
* **quote:** make QuoteShort and AftermarketTrade fields optional ([716455c](716455c))
* **responses:** make omittable fundraising and sec filings members optional ([4850095](4850095))
* **responses:** make omittable news, market hours, esg and congressional members optional ([9ce3a15](9ce3a15))
* **sdk/go:** add DateOrYear temporal type ([d9de466](d9de466))
* **search:** make omittable ExchangeVariant and screener members optional ([b79c55b](b79c55b))
* **statements:** make FMP-omittable statement members optional ([d4fde87](d4fde87))
* **statements:** make pre-IPO stub-quarter amounts optional ([683b04e](683b04e))

### ♨️ CI, Workflows & Configs

* **env:** add .envrc for direnv configuration ([#373](#373)) ([78da933](78da933))

### 🪲 Bug Fixes

* **bulk:** decode final seven bulk routes as text/csv ([78aa5f9](78aa5f9)), closes [#376](#376)
* **bulk:** decode metric bulk routes as CSV ([21b5c9b](21b5c9b)), closes [#376](#376)
* **bulk:** decode snapshot bulk routes as text/csv ([d30ffc2](d30ffc2))
* **bulk:** make balance-sheet numeric members optional ([5665926](5665926))
* **bulk:** make bulk income numeric members optional ([73e45f6](73e45f6))
* **bulk:** make empty numeric snapshot cells optional per ADR 0035 ([473402f](473402f)), closes [#376](#376)
* **bulk:** make numeric cash-flow and EOD members optional ([514567e](514567e))
* **bulk:** make numeric metric members optional for empty cells ([22ca885](22ca885))
* **calendar:** decode a bare year ipoDate as a year, not a date ([ac0c07b](ac0c07b)), closes [#379](#379) [#379](#379)
* **company:** make profile isin, country and change optional ([23fb211](23fb211)), closes [#376](#376)
* **csv:** strip leading UTF-8 BOM before the Go CSV header ([7c8cd51](7c8cd51))
* **fmp-py-gen:** resolve CSV contract in wire resolver and gen_go ([77c3d08](77c3d08)), closes [#376](#376)
* **fmp-py:** map provider error bodies to FmpStatusError ([b206669](b206669))
* **fmp-py:** return None from client __exit__ to propagate exceptions ([9e18f76](9e18f76))
* **funds:** decode "NULL" entityOrgType as absent ([2e07672](2e07672)), closes [#380](#380)
* **indexes:** keep IndexConstituent.founded verbatim as a string ([ac87c1a](ac87c1a)), closes [#378](#378)
* **libfmp:** add CSV response contract and row decoder ([afee377](afee377)), closes [#376](#376)
* **libfmp:** raise CSV bulk body limit to 256 MiB default ([a25b8db](a25b8db)), closes [#376](#376)
* **libfmp:** require every CSV row member to be a header column ([780c562](780c562)), closes [#376](#376)
* **libfmp:** treat FMP error messages on HTTP 200 as status errors ([f570df9](f570df9))
* **responses:** decode congressional net worth as fractional and optional ([95c0685](95c0685))
* **sdk/go/artifact:** route member unmarshal errors through memberDecodeError ([5d00bf4](5d00bf4))
* **sdk/go:** handle text/csv bulk responses with larger body limit ([1b4a66b](1b4a66b)), closes [#376](#376)
* **sdk/go:** keep member path on nullable and codec decode failures ([c163be0](c163be0))
* **sdk/go:** require every model member to be a CSV header column ([9f0e19e](9f0e19e)), closes [#376](#376)
* **sdk/go:** treat FMP error messages on HTTP 200 as status errors ([27c4ed9](27c4ed9))
* **sdk:** wrap member decode errors with field context ([#402](#402)) ([2356304](2356304))
* **statements:** return one financial report json object not a list ([3e7eb61](3e7eb61))
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.

1 participant