@@ -9,7 +9,7 @@ import { EventListenerName } from "@src/enums";
99import { triggerEvent } from "@src/hooks" ;
1010
1111export const useChatbotIframeConnection = ( iframeRef : React . RefObject < HTMLIFrameElement > , onConnect ?: ( ) => void ) => {
12- const { t } = useTranslation ( "chatbot" , { keyPrefix : "iframeComponent" } ) ;
12+ const { t } = useTranslation ( "chatbot" ) ;
1313
1414 const [ isLoading , setIsLoading ] = useState < boolean > ( true ) ;
1515 const [ loadError , setLoadError ] = useState < string | null > ( null ) ;
@@ -44,8 +44,8 @@ export const useChatbotIframeConnection = (iframeRef: React.RefObject<HTMLIFrame
4444
4545 const eventErrorDetail = detail || localizedBaseMessage ;
4646 triggerEvent ( EventListenerName . iframeError , {
47- message : tRef . current ( "connectionError" ) ,
48- error : tRef . current ( "connectionErrorExtended" , { error : eventErrorDetail } ) ,
47+ message : tRef . current ( "iframeComponent. connectionError" ) ,
48+ error : tRef . current ( "iframeComponent. connectionErrorExtended" , { error : eventErrorDetail } ) ,
4949 } ) ;
5050 } , [ ] ) ;
5151
@@ -65,22 +65,63 @@ export const useChatbotIframeConnection = (iframeRef: React.RefObject<HTMLIFrame
6565 let isMounted = true ;
6666 const currentIframe = iframeRef . current ;
6767 let timeoutId : number | undefined = undefined ;
68+ let retryTimeoutId : number | undefined = undefined ;
6869
6970 iframeCommService . setIframe ( currentIframe ) ;
7071
71- const connectAsync = async ( ) => {
72+ const connectionConfig = {
73+ maxRetries : 3 ,
74+ retryDelay : 2000 ,
75+ } as const ;
76+
77+ const scheduleRetry = ( reason : string , retryCount : number , errorType : string , errorDetail : string ) : boolean => {
78+ if ( retryCount < connectionConfig . maxRetries && isMounted ) {
79+ LoggerService . debug (
80+ namespaces . chatbot ,
81+ t ( "errors.serverRespondedWithStatus" , {
82+ reason,
83+ retryDelay : connectionConfig . retryDelay ,
84+ currentAttempt : retryCount + 1 ,
85+ maxAttempts : connectionConfig . maxRetries + 1 ,
86+ } )
87+ ) ;
88+ retryTimeoutId = window . setTimeout ( ( ) => {
89+ if ( isMounted ) {
90+ connectAsync ( retryCount + 1 ) ;
91+ }
92+ } , connectionConfig . retryDelay ) ;
93+ return true ;
94+ }
95+
96+ isConnectingRef . current = false ;
97+ handleError ( errorType , errorDetail ) ;
98+ return false ;
99+ } ;
100+
101+ const connectAsync = async ( retryCount = 0 ) => {
72102 try {
73103 const response = await fetch ( aiChatbotUrl , { method : "HEAD" , credentials : "include" } ) ;
74104 if ( ! response . ok ) {
75105 if ( isMounted ) {
76- handleError ( "connectionRefused" , `Server responded with status ${ response . status } ` ) ;
106+ scheduleRetry (
107+ `Server responded with status ${ response . status } ` ,
108+ retryCount ,
109+ "connectionRefused" ,
110+ `Server responded with status ${ response . status } `
111+ ) ;
77112 }
78113 return ;
79114 }
80115
81116 timeoutId = window . setTimeout ( ( ) => {
82117 if ( isLoadingRef . current && isMounted ) {
83- handleError ( "connectionError" , "Timeout waiting for iframe connection" ) ;
118+ if ( timeoutId ) clearTimeout ( timeoutId ) ;
119+ scheduleRetry (
120+ "Connection timeout" ,
121+ retryCount ,
122+ "connectionError" ,
123+ "Timeout waiting for iframe connection"
124+ ) ;
84125 }
85126 } , chatbotIframeConnectionTimeout ) ;
86127
@@ -95,15 +136,13 @@ export const useChatbotIframeConnection = (iframeRef: React.RefObject<HTMLIFrame
95136 setIsRetryLoading ( false ) ;
96137 } , 1750 ) ;
97138 onConnectRef . current ?.( ) ;
139+ isConnectingRef . current = false ;
98140 }
99141 } catch ( error ) {
100142 if ( timeoutId ) clearTimeout ( timeoutId ) ;
101143 if ( isMounted ) {
102- handleError ( "connectionError" , error instanceof Error ? error . message : String ( error ) ) ;
103- }
104- } finally {
105- if ( isMounted ) {
106- isConnectingRef . current = false ;
144+ const errorMessage = error instanceof Error ? error . message : String ( error ) ;
145+ scheduleRetry ( `Connection error: ${ errorMessage } ` , retryCount , "connectionError" , errorMessage ) ;
107146 }
108147 }
109148 } ;
@@ -116,9 +155,12 @@ export const useChatbotIframeConnection = (iframeRef: React.RefObject<HTMLIFrame
116155 if ( timeoutId ) {
117156 clearTimeout ( timeoutId ) ;
118157 }
158+ if ( retryTimeoutId ) {
159+ clearTimeout ( retryTimeoutId ) ;
160+ }
119161 } ;
120162 // eslint-disable-next-line react-hooks/exhaustive-deps
121- } , [ iframeRef , isIframeElementLoaded ] ) ;
163+ } , [ iframeRef , isIframeElementLoaded , t ] ) ;
122164
123165 const handleRetry = useCallback ( ( ) => {
124166 if ( iframeRef . current ) {
@@ -135,20 +177,21 @@ export const useChatbotIframeConnection = (iframeRef: React.RefObject<HTMLIFrame
135177 url . searchParams . set ( "retry" , Date . now ( ) . toString ( ) ) ;
136178 iframeRef . current . src = url . toString ( ) ;
137179 } catch ( error ) {
138- LoggerService . error ( namespaces . chatbot , `Error setting iframe src: ${ error } ` ) ;
180+ LoggerService . error ( namespaces . chatbot , t ( "errors.errorSettingIframeSrc" , { error } ) ) ;
139181 }
140182
141183 setTimeout ( ( ) => {
142184 setIsRetryLoading ( false ) ;
143185 } , 1750 ) ;
144186 } else {
145- LoggerService . error ( namespaces . chatbot , "iframeRef.current is null, cannot retry" ) ;
187+ LoggerService . error ( namespaces . chatbot , t ( "errors.iframeRefIsNull" ) ) ;
146188 setTimeout ( ( ) => {
147189 setIsRetryLoading ( false ) ;
148190 } , 1750 ) ;
149191 }
150192 // eslint-disable-next-line react-hooks/exhaustive-deps
151- } , [ iframeRef , aiChatbotUrl ] ) ;
193+ } , [ iframeRef , aiChatbotUrl , t ] ) ;
194+
152195 return {
153196 isLoading,
154197 loadError,
0 commit comments