Skip to content

fix: replace non-null assertions with guard checks in limitless#570

Merged
realfishsam merged 1 commit into
mainfrom
fix/560-limitless-assertions
May 24, 2026
Merged

fix: replace non-null assertions with guard checks in limitless#570
realfishsam merged 1 commit into
mainfrom
fix/560-limitless-assertions

Conversation

@realfishsam

Copy link
Copy Markdown
Contributor

Fixes #560

@realfishsam

Copy link
Copy Markdown
Contributor Author

PR Review: VERIFIED

What This Does

Replaces non-null assertions (!) with explicit guard-and-throw checks in the Limitless exchange class for optional fetcher/normalizer methods. The methods (fetchRawOHLCV, fetchRawOrderBook, fetchRawTrades, fetchRawMyTrades, normalizeOHLCV, normalizeOrderBook, normalizeTrade, normalizeUserTrade, normalizePosition) are declared as optional in the ExchangeFetcher/ExchangeNormalizer interfaces, so the non-null assertions were suppressing real type-safety.

Blast Radius

  • Core exchange: Limitless only (core/src/exchanges/limitless/index.ts)
  • Affects: fetchOHLCV, fetchOrderBook, fetchTrades, fetchMyTrades, fetchPositions
  • No SDK/OpenAPI/other exchange impact

Findings

  1. All 9 non-null assertions are replaced with proper guards. Error messages are descriptive ("fetchRawOHLCV is not implemented for this exchange").
  2. For fetchTrades and fetchMyTrades, the normalizer method is captured to a local variable before the .map() call (const normalizeTrade = this.normalizer.normalizeTrade). This is necessary because TypeScript cannot narrow optional methods inside callback closures. Correct pattern.
  3. For fetchPositions, the same local-variable capture pattern is used for normalizePosition. Consistent.
  4. The fetchRawPositions call on line 440 does NOT get a guard -- this is correct because fetchRawPositions is a non-optional method in the interface (it's always implemented).
  5. The Limitless fetcher/normalizer actually implement all these methods (confirmed via grep of fetcher.ts and normalizer.ts), so the guards will never fire at runtime today. But they provide correct type-safety if the interface contracts change.

PMXT Pipeline Check

  • Field propagation: N/A
  • OpenAPI sync: N/A
  • Type safety: OK -- strictly improves type safety by replacing compile-time suppression with runtime validation

Semver Impact

patch -- no API change. The new Error throws replace what would have been TypeError: undefined is not a function at runtime.

Risk

Low. The guards are technically dead code today (Limitless implements all these methods), but they provide correct defense against future interface changes. No behavioral change for working calls.

@realfishsam realfishsam merged commit 1bc7dc1 into main May 24, 2026
11 of 12 checks passed
@realfishsam realfishsam deleted the fix/560-limitless-assertions branch May 24, 2026 17:04
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.

[non-null] limitless/index.ts: 9 unsafe assertions on optional interface methods

1 participant