@@ -12,6 +12,21 @@ public struct TradingPair {
1212struct PriceResponse : Codable {
1313 let price : Double
1414 let timestamp : Double
15+
16+ init ( from decoder: Decoder ) throws {
17+ let container = try decoder. container ( keyedBy: CodingKeys . self)
18+ timestamp = try container. decode ( Double . self, forKey: . timestamp)
19+
20+ // Handle price as either String or Double
21+ if let priceString = try ? container. decode ( String . self, forKey: . price) {
22+ guard let priceValue = Double ( priceString) else {
23+ throw DecodingError . dataCorruptedError ( forKey: . price, in: container, debugDescription: " Price string is not a valid number " )
24+ }
25+ price = priceValue
26+ } else {
27+ price = try container. decode ( Double . self, forKey: . price)
28+ }
29+ }
1530}
1631
1732struct CandleResponse : Codable {
@@ -47,6 +62,7 @@ enum PriceServiceError: Error {
4762 case invalidPair
4863 case networkError
4964 case decodingError
65+ case noPriceDataAvailable
5066}
5167
5268// MARK: - Trading Pairs Constants
@@ -140,24 +156,36 @@ class PriceService {
140156 }
141157
142158 /// Fetches fresh data from API (always hits the network)
159+ /// Individual pair failures are logged but don't fail the entire request - only fails if ALL pairs fail
143160 @discardableResult
144161 private func fetchFreshData( pairs: [ String ] , period: GraphPeriod ) async throws -> [ PriceData ] {
145- let priceDataArray = try await withThrowingTaskGroup ( of: PriceData . self) { group in
162+ let priceDataArray = await withTaskGroup ( of: PriceData ? . self) { group in
146163 var results : [ PriceData ] = [ ]
147164
148165 for pairName in pairs {
149166 group. addTask {
150- try await self . fetchPairData ( pairName: pairName, period: period)
167+ do {
168+ return try await self . fetchPairData ( pairName: pairName, period: period)
169+ } catch {
170+ Logger . warn ( " Failed to fetch price data for \( pairName) : \( error. localizedDescription) " )
171+ return nil
172+ }
151173 }
152174 }
153175
154- for try await priceData in group {
155- results. append ( priceData)
176+ for await priceData in group {
177+ if let data = priceData {
178+ results. append ( data)
179+ }
156180 }
157181
158182 return results
159183 }
160184
185+ guard !priceDataArray. isEmpty else {
186+ throw PriceServiceError . noPriceDataAvailable
187+ }
188+
161189 return priceDataArray
162190 }
163191
0 commit comments