@@ -24,6 +24,7 @@ import { StackedTextHLBox } from '../common/StackedTextHLBox';
2424import { TokenIcon } from '../common/TokenIcon' ;
2525import { PoolHeader } from '../pool/PoolHeader' ;
2626import { PoolHealthBanner } from '../pool/PoolHealthBanner' ;
27+ import { PoolLoadError } from '../pool/PoolLoadErrorBanner' ;
2728import { MarketCardCollapse } from './MarketCardCollapse' ;
2829
2930export interface MarketCardProps extends PoolComponentProps {
@@ -44,10 +45,10 @@ export const MarketCard: React.FC<MarketCardProps> = ({ poolId, index, onLoaded,
4445 const theme = useTheme ( ) ;
4546 const { trackPool, viewType } = useSettings ( ) ;
4647
47- const { data : poolMeta } = usePoolMeta ( poolId ) ;
48+ const { data : poolMeta , error : poolMetaError , isError : isPoolMetaError } = usePoolMeta ( poolId ) ;
4849 const { data : backstop } = useBackstop ( poolMeta ?. version ) ;
49- const { data : pool } = usePool ( poolMeta ) ;
50- const { data : poolOracle } = usePoolOracle ( pool ) ;
50+ const { data : pool , isError : isPoolError } = usePool ( poolMeta ) ;
51+ const { data : poolOracle , isError : isOracleError } = usePoolOracle ( pool ) ;
5152 const { data : backstopPool } = useBackstopPool ( poolMeta ) ;
5253 const [ expand , setExpand ] = useState ( false ) ;
5354 const [ rotateArrow , setRotateArrow ] = useState ( false ) ;
@@ -58,14 +59,65 @@ export const MarketCard: React.FC<MarketCardProps> = ({ poolId, index, onLoaded,
5859 const tokenMetadataList = useTokenMetadataList ( pool ? Array . from ( pool . reserves . keys ( ) ) : [ ] ) ;
5960
6061 useEffect ( ( ) => {
62+ // Handle poolMeta errors — call onLoaded so progressive loading doesn't stall
63+ if ( isPoolMetaError ) {
64+ onLoaded ( poolId , index , {
65+ name : '' ,
66+ poolTvl : 0 ,
67+ backstopTvl : 0 ,
68+ tokenMetadataList : [ ] ,
69+ } ) ;
70+ return ;
71+ }
72+
73+ // Handle pool load errors when poolMeta is available
74+ if ( poolMeta !== undefined && isPoolError ) {
75+ onLoaded ( poolId , index , {
76+ name : poolMeta . name ,
77+ poolTvl : 0 ,
78+ backstopTvl : 0 ,
79+ tokenMetadataList : [ ] ,
80+ } ) ;
81+ trackPool ( poolMeta ) ;
82+ return ;
83+ }
84+
85+ // Handle oracle errors — render card with unknown TVL but real backstop data
86+ if (
87+ poolMeta !== undefined &&
88+ pool !== undefined &&
89+ backstopPool !== undefined &&
90+ backstop !== undefined &&
91+ isOracleError
92+ ) {
93+ const backstopPoolEst = BackstopPoolEst . build (
94+ backstop . backstopToken ,
95+ backstopPool . poolBalance
96+ ) ;
97+ const processedTokenMetadata : ReserveTokenMetadata [ ] = tokenMetadataList
98+ . filter ( ( result ) => result . data !== undefined )
99+ . map ( ( result ) => result . data ! )
100+ . filter ( ( data ) : data is ReserveTokenMetadata => data !== null ) ;
101+
102+ onLoaded ( poolId , index , {
103+ name : poolMeta . name ,
104+ poolTvl : 0 ,
105+ backstopTvl : backstopPoolEst ?. totalSpotValue ?? 0 ,
106+ tokenMetadataList : processedTokenMetadata ,
107+ } ) ;
108+ trackPool ( poolMeta ) ;
109+ return ;
110+ }
111+
112+ // All data loaded successfully
61113 if (
62114 poolMeta !== undefined &&
63115 pool !== undefined &&
64116 backstopPool !== undefined &&
65117 backstop !== undefined &&
66118 poolOracle !== undefined
67119 ) {
68- const poolEst = poolOracle ? PoolEstimate . build ( pool . reserves , poolOracle ) : undefined ;
120+ const poolEst = PoolEstimate . build ( pool . reserves , poolOracle ) ;
69121 const backstopPoolEst = BackstopPoolEst . build (
70122 backstop . backstopToken ,
71123 backstopPool . poolBalance
@@ -77,18 +129,58 @@ export const MarketCard: React.FC<MarketCardProps> = ({ poolId, index, onLoaded,
77129
78130 onLoaded ( poolId , index , {
79131 name : poolMeta . name ,
80- poolTvl : poolEst ? poolEst . totalSupply - poolEst . totalBorrowed : 0 ,
132+ poolTvl : poolEst . totalSupply - poolEst . totalBorrowed ,
81133 backstopTvl : backstopPoolEst ?. totalSpotValue ?? 0 ,
82134 tokenMetadataList : processedTokenMetadata ,
83135 } ) ;
84136 trackPool ( poolMeta ) ;
85137 }
86- } , [ pool , backstopPool , backstop , poolOracle , tokenMetadataList ] ) ;
138+ } , [
139+ pool ,
140+ backstopPool ,
141+ backstop ,
142+ poolOracle ,
143+ tokenMetadataList ,
144+ isOracleError ,
145+ isPoolError ,
146+ isPoolMetaError ,
147+ ] ) ;
148+
149+ // poolMeta failed to load (other error) — show error banner with contract ID
150+ if ( isPoolMetaError ) {
151+ return (
152+ < Section
153+ width = { SectionSize . FULL }
154+ sx = { { flexDirection : 'column' , marginBottom : '12px' , ...sx } }
155+ >
156+ < PoolLoadError poolId = { poolId } />
157+ </ Section >
158+ ) ;
159+ }
160+
161+ // Pool data failed to load but poolMeta is available — show header + error banner
162+ if ( poolMeta !== undefined && isPoolError ) {
163+ return (
164+ < Section
165+ width = { SectionSize . FULL }
166+ sx = { { flexDirection : 'column' , marginBottom : '12px' , ...sx } }
167+ >
168+ < Row >
169+ < PoolHeader
170+ name = { poolMeta . name }
171+ version = { poolMeta . version }
172+ sx = { { margin : '6px' , padding : '6px' } }
173+ />
174+ </ Row >
175+ < PoolLoadError poolId = { poolId } poolName = { poolMeta . name } />
176+ </ Section >
177+ ) ;
178+ }
87179
180+ // Still loading — no errors yet, data not ready
88181 if (
89182 poolMeta === undefined ||
90183 pool === undefined ||
91- poolOracle === undefined ||
92184 backstopPool === undefined ||
93185 backstop === undefined
94186 ) {
0 commit comments