11import { useQuery } from '@tanstack/react-query'
2- import { useEffect , useMemo , useState } from 'react'
2+ import { useEffect , useMemo , useRef , useState } from 'react'
33import { foreignMarketApi } from '@/api/market'
44import { DAY_MS , DEFAULT_MINUTE_INTERVAL } from '@/features/invest/constants'
55import { formatApiDate } from '@/features/invest/formatters'
@@ -19,6 +19,52 @@ const STALE = {
1919 orderBook : 1000 * 5 ,
2020}
2121
22+ function resolveQueryErrorMessage ( error , fallbackMessage ) {
23+ const rawMessage = typeof error ?. message === 'string' ? error . message . trim ( ) : ''
24+
25+ if ( ! rawMessage ) return fallbackMessage
26+ if ( rawMessage . startsWith ( '해외주식 API 호출 실패' ) ) return fallbackMessage
27+ if ( rawMessage === '시장 데이터를 불러오지 못했습니다.' ) return fallbackMessage
28+
29+ return rawMessage
30+ }
31+
32+ function useQueryErrorLogger ( label , error , context ) {
33+ const lastSignatureRef = useRef ( '' )
34+
35+ useEffect ( ( ) => {
36+ if ( ! error ) {
37+ lastSignatureRef . current = ''
38+ return
39+ }
40+
41+ const signature = [
42+ label ,
43+ error . url ?? '' ,
44+ error . status ?? '' ,
45+ error . code ?? '' ,
46+ error . message ?? '' ,
47+ context . stockCode ,
48+ context . exchcd ,
49+ ] . join ( '|' )
50+
51+ if ( lastSignatureRef . current === signature ) return
52+ lastSignatureRef . current = signature
53+
54+ console . error ( `[foreign-market] ${ label } query failed` , {
55+ ...context ,
56+ url : error . url ?? null ,
57+ status : error . status ?? null ,
58+ statusText : error . statusText ?? '' ,
59+ code : error . code ?? null ,
60+ message : error . message ?? '' ,
61+ data : error . data ?? null ,
62+ rawText : error . rawText ?? null ,
63+ error,
64+ } )
65+ } , [ context , error , label ] )
66+ }
67+
2268export default function useForeignMarketData ( stockCode , exchcd , { enabled, initialPeriod, initialMinuteInterval } ) {
2369 const [ selectedChartPeriod , setSelectedChartPeriod ] = useState (
2470 ( ) => initialPeriod ?? localStorage . getItem ( 'invest.chartPeriod' ) ?? 'MINUTE' ,
@@ -63,6 +109,16 @@ export default function useForeignMarketData(stockCode, exchcd, { enabled, initi
63109 staleTime : STALE . orderBook ,
64110 } )
65111
112+ const errorLogContext = useMemo ( ( ) => ( {
113+ stockCode,
114+ exchcd,
115+ } ) , [ exchcd , stockCode ] )
116+
117+ useQueryErrorLogger ( 'price' , priceQuery . error , errorLogContext )
118+ useQueryErrorLogger ( 'daily-chart' , dailyChartQuery . error , errorLogContext )
119+ useQueryErrorLogger ( 'minute-chart' , minuteChartQuery . error , errorLogContext )
120+ useQueryErrorLogger ( 'order-book' , orderBookQuery . error , errorLogContext )
121+
66122 const usesBaseMinuteData = selectedChartPeriod === 'MINUTE' && selectedMinuteInterval === DEFAULT_MINUTE_INTERVAL
67123 const needsCustomChart = enabled && ! usesBaseMinuteData && selectedChartPeriod !== 'DAILY'
68124
@@ -87,20 +143,35 @@ export default function useForeignMarketData(stockCode, exchcd, { enabled, initi
87143 staleTime : selectedChartPeriod === 'MINUTE' ? STALE . minuteChart : STALE . dailyChart ,
88144 } )
89145
146+ useQueryErrorLogger ( 'custom-chart' , customChartQuery . error , {
147+ ...errorLogContext ,
148+ chartPeriod : selectedChartPeriod ,
149+ minuteInterval : selectedMinuteInterval ,
150+ } )
151+
90152 const dailySeries = normalizeForeignDailySeries ( dailyChartQuery . data ?. dataPoints )
91153 const minuteSeries = normalizeForeignMinuteSeries ( minuteChartQuery . data ?. dataPoints )
92154
93155 const priceData = priceQuery . data
94156 ? { currentPrice : priceQuery . data . price , changeAmount : priceQuery . data . diff , changeRate : priceQuery . data . rate }
95157 : null
96158
159+ const marketError = priceQuery . error || dailyChartQuery . error || minuteChartQuery . error
160+ const marketErrorMessage = resolveQueryErrorMessage ( marketError , '현재 해외주식 시세를 불러오지 못하고 있습니다.' )
161+ const dailyErrorMessage = resolveQueryErrorMessage ( dailyChartQuery . error , '현재 해외주식 일별 시세를 불러오지 못하고 있습니다.' )
162+ const minuteErrorMessage = resolveQueryErrorMessage ( minuteChartQuery . error , '현재 해외주식 실시간 시세를 불러오지 못하고 있습니다.' )
163+ const orderBookErrorMessage = resolveQueryErrorMessage ( orderBookQuery . error , '현재 해외주식 호가 정보를 불러오지 못하고 있습니다.' )
164+ const customChartErrorMessage = resolveQueryErrorMessage ( customChartQuery . error , '현재 해외주식 차트 데이터를 불러오지 못하고 있습니다.' )
165+
97166 const marketState = {
98167 isLoading : priceQuery . isLoading || dailyChartQuery . isLoading || minuteChartQuery . isLoading || orderBookQuery . isLoading ,
99- errorMessage : ( priceQuery . error || dailyChartQuery . error || minuteChartQuery . error || orderBookQuery . error ) ?. message ?? '' ,
168+ errorMessage : marketError ? marketErrorMessage : '' ,
100169 dailyLoading : dailyChartQuery . isLoading ,
101- dailyErrorMessage : dailyChartQuery . error ?. message ?? '' ,
170+ dailyErrorMessage : dailyChartQuery . error ? dailyErrorMessage : '' ,
102171 minuteLoading : minuteChartQuery . isLoading ,
103- minuteErrorMessage : minuteChartQuery . error ?. message ?? '' ,
172+ minuteErrorMessage : minuteChartQuery . error ? minuteErrorMessage : '' ,
173+ orderBookLoading : orderBookQuery . isLoading ,
174+ orderBookErrorMessage : orderBookQuery . error ? orderBookErrorMessage : '' ,
104175 priceData,
105176 dailySeries,
106177 minuteSeries,
@@ -117,7 +188,7 @@ export default function useForeignMarketData(stockCode, exchcd, { enabled, initi
117188
118189 const chartState = {
119190 isLoading : customChartQuery . isLoading ,
120- errorMessage : customChartQuery . error ?. message ?? '' ,
191+ errorMessage : customChartQuery . error ? customChartErrorMessage : '' ,
121192 series : customSeries ,
122193 }
123194
0 commit comments