@@ -13,12 +13,14 @@ import { readFileSync } from './util/fs'
1313
1414const debug = Debug ( 'api' )
1515let MAX_RETRY_LIMIT
16+ let RETRY_DELAY_BASE = 200 // Default base delay in milliseconds
17+ let TIMEOUT = 30000 // Default timeout in milliseconds
1618let Contentstack
1719
1820/**
1921 * @description Initialize sync utilities API requests
2022 * @param {Object } contentstack - Contentstack configuration details
21- */
23+ */
2224export const init = ( contentstack ) => {
2325 const packageInfo : any = JSON . parse ( readFileSync ( join ( __dirname , '..' , 'package.json' ) ) )
2426 Contentstack = contentstack
@@ -35,6 +37,14 @@ export const init = (contentstack) => {
3537 if ( Contentstack . MAX_RETRY_LIMIT ) {
3638 MAX_RETRY_LIMIT = Contentstack . MAX_RETRY_LIMIT
3739 }
40+
41+ if ( Contentstack . RETRY_DELAY_BASE ) {
42+ RETRY_DELAY_BASE = Contentstack . RETRY_DELAY_BASE
43+ }
44+
45+ if ( Contentstack . TIMEOUT ) {
46+ TIMEOUT = Contentstack . TIMEOUT
47+ }
3848}
3949
4050/**
@@ -60,13 +70,14 @@ export const get = (req, RETRY = 1) => {
6070 path : sanitizeUrl ( encodeURI ( req . path ) ) ,
6171 port : Contentstack . port ,
6272 protocol : Contentstack . protocol ,
73+ timeout : TIMEOUT , // Configurable timeout to prevent socket hang ups
6374 }
6475
6576 try {
6677 debug ( `${ options . method . toUpperCase ( ) } : ${ options . path } ` )
6778 let timeDelay
6879 let body = ''
69- request ( options , ( response ) => {
80+ const httpRequest = request ( options , ( response ) => {
7081
7182 response
7283 . setEncoding ( 'utf-8' )
@@ -76,8 +87,8 @@ export const get = (req, RETRY = 1) => {
7687 if ( response . statusCode >= 200 && response . statusCode <= 399 ) {
7788 return resolve ( JSON . parse ( body ) )
7889 } else if ( response . statusCode === 429 ) {
79- timeDelay = Math . pow ( Math . SQRT2 , RETRY ) * 200
80- debug ( `API rate limit exceeded. Retrying ${ options . path } with ${ timeDelay } sec delay` )
90+ timeDelay = Math . pow ( Math . SQRT2 , RETRY ) * RETRY_DELAY_BASE
91+ debug ( `API rate limit exceeded. Retrying ${ options . path } with ${ timeDelay } ms delay` )
8192
8293 return setTimeout ( ( ) => {
8394 return get ( req , RETRY )
@@ -86,8 +97,8 @@ export const get = (req, RETRY = 1) => {
8697 } , timeDelay )
8798 } else if ( response . statusCode >= 500 ) {
8899 // retry, with delay
89- timeDelay = Math . pow ( Math . SQRT2 , RETRY ) * 200
90- debug ( `Retrying ${ options . path } with ${ timeDelay } sec delay` )
100+ timeDelay = Math . pow ( Math . SQRT2 , RETRY ) * RETRY_DELAY_BASE
101+ debug ( `Retrying ${ options . path } with ${ timeDelay } ms delay` )
91102 RETRY ++
92103
93104 return setTimeout ( ( ) => {
@@ -102,8 +113,35 @@ export const get = (req, RETRY = 1) => {
102113 }
103114 } )
104115 } )
105- . on ( 'error' , reject )
106- . end ( )
116+
117+ // Set socket timeout to handle socket hang ups
118+ httpRequest . setTimeout ( options . timeout , ( ) => {
119+ debug ( `Request timeout for ${ options . path || 'unknown' } ` )
120+ httpRequest . destroy ( )
121+ reject ( new Error ( 'Request timeout' ) )
122+ } )
123+
124+ // Enhanced error handling for socket hang ups and connection resets
125+ httpRequest . on ( 'error' , ( error : any ) => {
126+ debug ( `Request error for ${ options . path || 'unknown' } : ${ error ?. message || 'Unknown error' } (${ error ?. code || 'NO_CODE' } )` )
127+
128+ // Handle socket hang up and connection reset errors with retry
129+ if ( ( error ?. code === 'ECONNRESET' || error ?. message ?. includes ( 'socket hang up' ) ) && RETRY <= MAX_RETRY_LIMIT ) {
130+ timeDelay = Math . pow ( Math . SQRT2 , RETRY ) * RETRY_DELAY_BASE
131+ debug ( `Socket hang up detected. Retrying ${ options . path || 'unknown' } with ${ timeDelay } ms delay (attempt ${ RETRY } /${ MAX_RETRY_LIMIT } )` )
132+ RETRY ++
133+
134+ return setTimeout ( ( ) => {
135+ return get ( req , RETRY )
136+ . then ( resolve )
137+ . catch ( reject )
138+ } , timeDelay )
139+ }
140+
141+ return reject ( error )
142+ } )
143+
144+ httpRequest . end ( )
107145 } catch ( error ) {
108146 return reject ( error )
109147 }
0 commit comments