@@ -32,10 +32,13 @@ export interface DataFetcherConfig<T> {
3232 successMessage ?: string ;
3333 /** Whether to show error toast on failure */
3434 showErrorToast ?: boolean ;
35+ /** Whether to show retry status in toasts */
36+ showRetryStatus ?: boolean ;
3537 /** Retry configuration */
3638 retry ?: {
3739 maxAttempts : number ;
3840 delay : number ;
41+ backoffMultiplier ?: number ;
3942 } ;
4043 /** Loading skeleton type */
4144 skeletonType ?: "text" | "card" | "list" | "table" | "graph" | "stats" ;
@@ -99,12 +102,33 @@ export const useDataFetcher = <T,>(config: DataFetcherConfig<T>) => {
99102 toast . error ( config . errorMessage || errorObj . message ) ;
100103 }
101104
102- // Handle retry logic
105+ // Handle retry logic with enhanced visibility
103106 if ( config . retry && retryCount < config . retry . maxAttempts ) {
104- setRetryCount ( ( prev ) => prev + 1 ) ;
107+ const nextRetryCount = retryCount + 1 ;
108+ const backoffMultiplier = config . retry . backoffMultiplier || 1 ;
109+ const delay = config . retry . delay * Math . pow ( backoffMultiplier , retryCount ) ;
110+
111+ setRetryCount ( nextRetryCount ) ;
112+
113+ // Show retry status toast if enabled
114+ if ( config . showRetryStatus ) {
115+ const remainingAttempts = config . retry . maxAttempts - nextRetryCount ;
116+ toast . info (
117+ `Retrying... Attempt ${ nextRetryCount } of ${ config . retry . maxAttempts } (${ remainingAttempts } remaining)` ,
118+ { autoClose : delay }
119+ ) ;
120+ }
121+
105122 setTimeout ( ( ) => {
106123 executeFetch ( ) ;
107- } , config . retry . delay ) ;
124+ } , delay ) ;
125+ } else if ( config . retry && retryCount >= config . retry . maxAttempts ) {
126+ // Show final failure message when all retries exhausted
127+ if ( config . showErrorToast ) {
128+ toast . error (
129+ config . errorMessage || `Failed after ${ config . retry . maxAttempts } attempts. Please try again later.`
130+ ) ;
131+ }
108132 }
109133
110134 throw errorObj ;
@@ -302,9 +326,11 @@ export const DataFetcherConfigs = {
302326 skeletonCount : 5 ,
303327 showSuccessToast : false ,
304328 showErrorToast : true ,
329+ showRetryStatus : true ,
305330 retry : {
306331 maxAttempts : 3 ,
307332 delay : 1000 ,
333+ backoffMultiplier : 1.5 ,
308334 } ,
309335 } ,
310336
@@ -314,7 +340,13 @@ export const DataFetcherConfigs = {
314340 skeletonCount : 6 ,
315341 showSuccessToast : false ,
316342 showErrorToast : true ,
343+ showRetryStatus : true ,
317344 errorMessage : "Search failed. Please try again." ,
345+ retry : {
346+ maxAttempts : 2 ,
347+ delay : 800 ,
348+ backoffMultiplier : 2 ,
349+ } ,
318350 } ,
319351
320352 /** Configuration for entity details */
@@ -323,9 +355,11 @@ export const DataFetcherConfigs = {
323355 skeletonCount : 1 ,
324356 showSuccessToast : false ,
325357 showErrorToast : true ,
358+ showRetryStatus : true ,
326359 retry : {
327360 maxAttempts : 2 ,
328361 delay : 500 ,
362+ backoffMultiplier : 1.5 ,
329363 } ,
330364 } ,
331365
@@ -336,9 +370,11 @@ export const DataFetcherConfigs = {
336370 showSuccessToast : true ,
337371 successMessage : "Graph data loaded successfully" ,
338372 showErrorToast : true ,
373+ showRetryStatus : true ,
339374 retry : {
340- maxAttempts : 1 ,
375+ maxAttempts : 2 ,
341376 delay : 2000 ,
377+ backoffMultiplier : 1.2 ,
342378 } ,
343379 } ,
344380} as const ;
0 commit comments