From cb08f6b1529591d1c895c866b4056a3bc07bf5c4 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Fri, 17 Jan 2025 16:06:23 -0300 Subject: [PATCH] Refactor WebhookController to implement retry logic for webhook requests - Introduced a new `retryWebhookRequest` method to handle retries for failed webhook requests, allowing up to 10 attempts with a delay of 30 seconds between each. - Updated error logging to provide detailed information on each retry attempt, including the attempt number and error details. - Enhanced existing webhook request handling to utilize the new retry logic, improving reliability in sending webhook data. - Modified error messages to be more informative, indicating when all retry attempts have failed. --- .../event/webhook/webhook.controller.ts | 63 +++++++++++++++++-- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/src/api/integrations/event/webhook/webhook.controller.ts b/src/api/integrations/event/webhook/webhook.controller.ts index 269a47c0..ce709c3d 100644 --- a/src/api/integrations/event/webhook/webhook.controller.ts +++ b/src/api/integrations/event/webhook/webhook.controller.ts @@ -5,7 +5,7 @@ import { wa } from '@api/types/wa.types'; import { configService, Log, Webhook } from '@config/env.config'; import { Logger } from '@config/logger.config'; import { BadRequestException } from '@exceptions'; -import axios from 'axios'; +import axios, { AxiosInstance } from 'axios'; import { isURL } from 'class-validator'; import { EmitData, EventController, EventControllerInterface } from '../event.controller'; @@ -117,12 +117,12 @@ export class WebhookController extends EventController implements EventControlle headers: webhookHeaders as Record | undefined, }); - await httpService.post('', webhookData); + await this.retryWebhookRequest(httpService, webhookData, `${origin}.sendData-Webhook`, baseURL, serverUrl); } } catch (error) { this.logger.error({ local: `${origin}.sendData-Webhook`, - message: error?.message, + message: `Todas as tentativas falharam: ${error?.message}`, hostName: error?.hostname, syscall: error?.syscall, code: error?.code, @@ -158,12 +158,18 @@ export class WebhookController extends EventController implements EventControlle if (isURL(globalURL)) { const httpService = axios.create({ baseURL: globalURL }); - await httpService.post('', webhookData); + await this.retryWebhookRequest( + httpService, + webhookData, + `${origin}.sendData-Webhook-Global`, + globalURL, + serverUrl, + ); } } catch (error) { this.logger.error({ local: `${origin}.sendData-Webhook-Global`, - message: error?.message, + message: `Todas as tentativas falharam: ${error?.message}`, hostName: error?.hostname, syscall: error?.syscall, code: error?.code, @@ -177,4 +183,51 @@ export class WebhookController extends EventController implements EventControlle } } } + + private async retryWebhookRequest( + httpService: AxiosInstance, + webhookData: any, + origin: string, + baseURL: string, + serverUrl: string, + maxRetries = 10, + delaySeconds = 30, + ): Promise { + let attempts = 0; + + while (attempts < maxRetries) { + try { + await httpService.post('', webhookData); + if (attempts > 0) { + this.logger.log({ + local: `${origin}`, + message: `Sucesso no envio após ${attempts + 1} tentativas`, + url: baseURL, + }); + } + return; + } catch (error) { + attempts++; + + this.logger.error({ + local: `${origin}`, + message: `Tentativa ${attempts}/${maxRetries} falhou: ${error?.message}`, + hostName: error?.hostname, + syscall: error?.syscall, + code: error?.code, + error: error?.errno, + stack: error?.stack, + name: error?.name, + url: baseURL, + server_url: serverUrl, + }); + + if (attempts === maxRetries) { + throw error; + } + + await new Promise((resolve) => setTimeout(resolve, delaySeconds * 1000)); + } + } + } }