@@ -115,6 +115,7 @@ export class WebhookController extends EventController implements EventControlle
115115 const httpService = axios . create ( {
116116 baseURL,
117117 headers : webhookHeaders as Record < string , string > | undefined ,
118+ timeout : webhookConfig . REQUEST ?. TIMEOUT_MS ?? 30000 ,
118119 } ) ;
119120
120121 await this . retryWebhookRequest ( httpService , webhookData , `${ origin } .sendData-Webhook` , baseURL , serverUrl ) ;
@@ -156,7 +157,10 @@ export class WebhookController extends EventController implements EventControlle
156157
157158 try {
158159 if ( regex . test ( globalURL ) ) {
159- const httpService = axios . create ( { baseURL : globalURL } ) ;
160+ const httpService = axios . create ( {
161+ baseURL : globalURL ,
162+ timeout : webhookConfig . REQUEST ?. TIMEOUT_MS ?? 30000 ,
163+ } ) ;
160164
161165 await this . retryWebhookRequest (
162166 httpService ,
@@ -190,12 +194,20 @@ export class WebhookController extends EventController implements EventControlle
190194 origin : string ,
191195 baseURL : string ,
192196 serverUrl : string ,
193- maxRetries = 10 ,
194- delaySeconds = 30 ,
197+ maxRetries ?: number ,
198+ delaySeconds ?: number ,
195199 ) : Promise < void > {
200+ const webhookConfig = configService . get < Webhook > ( 'WEBHOOK' ) ;
201+ const maxRetryAttempts = maxRetries ?? webhookConfig . RETRY ?. MAX_ATTEMPTS ?? 10 ;
202+ const initialDelay = delaySeconds ?? webhookConfig . RETRY ?. INITIAL_DELAY_SECONDS ?? 5 ;
203+ const useExponentialBackoff = webhookConfig . RETRY ?. USE_EXPONENTIAL_BACKOFF ?? true ;
204+ const maxDelay = webhookConfig . RETRY ?. MAX_DELAY_SECONDS ?? 300 ;
205+ const jitterFactor = webhookConfig . RETRY ?. JITTER_FACTOR ?? 0.2 ;
206+ const nonRetryableStatusCodes = webhookConfig . RETRY ?. NON_RETRYABLE_STATUS_CODES ?? [ 400 , 401 , 403 , 404 , 422 ] ;
207+
196208 let attempts = 0 ;
197209
198- while ( attempts < maxRetries ) {
210+ while ( attempts < maxRetryAttempts ) {
199211 try {
200212 await httpService . post ( '' , webhookData ) ;
201213 if ( attempts > 0 ) {
@@ -208,25 +220,54 @@ export class WebhookController extends EventController implements EventControlle
208220 return ;
209221 } catch ( error ) {
210222 attempts ++ ;
223+
224+ const isTimeout = error . code === 'ECONNABORTED' ;
225+
226+ if ( error ?. response ?. status && nonRetryableStatusCodes . includes ( error . response . status ) ) {
227+ this . logger . error ( {
228+ local : `${ origin } ` ,
229+ message : `Erro não recuperável (${ error . response . status } ): ${ error ?. message } . Cancelando retentativas.` ,
230+ statusCode : error ?. response ?. status ,
231+ url : baseURL ,
232+ server_url : serverUrl ,
233+ } ) ;
234+ throw error ;
235+ }
211236
212237 this . logger . error ( {
213238 local : `${ origin } ` ,
214- message : `Tentativa ${ attempts } /${ maxRetries } falhou: ${ error ?. message } ` ,
239+ message : `Tentativa ${ attempts } /${ maxRetryAttempts } falhou: ${ isTimeout ? 'Timeout da requisição' : error ?. message } ` ,
215240 hostName : error ?. hostname ,
216241 syscall : error ?. syscall ,
217242 code : error ?. code ,
243+ isTimeout,
244+ statusCode : error ?. response ?. status ,
218245 error : error ?. errno ,
219246 stack : error ?. stack ,
220247 name : error ?. name ,
221248 url : baseURL ,
222249 server_url : serverUrl ,
223250 } ) ;
224251
225- if ( attempts === maxRetries ) {
252+ if ( attempts === maxRetryAttempts ) {
226253 throw error ;
227254 }
228255
229- await new Promise ( ( resolve ) => setTimeout ( resolve , delaySeconds * 1000 ) ) ;
256+ let nextDelay = initialDelay ;
257+ if ( useExponentialBackoff ) {
258+ nextDelay = Math . min ( initialDelay * Math . pow ( 2 , attempts - 1 ) , maxDelay ) ;
259+
260+ const jitter = nextDelay * jitterFactor * ( Math . random ( ) * 2 - 1 ) ;
261+ nextDelay = Math . max ( initialDelay , nextDelay + jitter ) ;
262+ }
263+
264+ this . logger . log ( {
265+ local : `${ origin } ` ,
266+ message : `Aguardando ${ nextDelay . toFixed ( 1 ) } segundos antes da próxima tentativa` ,
267+ url : baseURL ,
268+ } ) ;
269+
270+ await new Promise ( ( resolve ) => setTimeout ( resolve , nextDelay * 1000 ) ) ;
230271 }
231272 }
232273 }
0 commit comments