From 03b00c49d5f6a952fe34032a6185f838aeeb36ff Mon Sep 17 00:00:00 2001 From: bosiraphael <71827178+bosiraphael@users.noreply.github.com> Date: Thu, 27 Jun 2024 09:57:19 +0200 Subject: [PATCH] Improve gmail error handling by catching and throttling for 400 failedPrecondition (#6044) Closes #5897 --- .../messaging-error-handling.service.ts | 136 +++++++++++++----- 1 file changed, 100 insertions(+), 36 deletions(-) diff --git a/packages/twenty-server/src/modules/messaging/common/services/messaging-error-handling.service.ts b/packages/twenty-server/src/modules/messaging/common/services/messaging-error-handling.service.ts index fb3c7b99d..327ce91ca 100644 --- a/packages/twenty-server/src/modules/messaging/common/services/messaging-error-handling.service.ts +++ b/packages/twenty-server/src/modules/messaging/common/services/messaging-error-handling.service.ts @@ -51,6 +51,21 @@ export class MessagingErrorHandlingService { workspaceId, ); } + if (reason === 'failedPrecondition') { + await this.handleFailedPrecondition( + error, + syncStep, + messageChannel, + workspaceId, + ); + } else { + await this.handleUnknownError( + error, + syncStep, + messageChannel, + workspaceId, + ); + } break; case 404: await this.handleNotFound(error, syncStep, messageChannel, workspaceId); @@ -152,44 +167,24 @@ export class MessagingErrorHandlingService { message: `${error.code}: ${error.reason}`, }); - if ( - messageChannel.throttleFailureCount >= MESSAGING_THROTTLE_MAX_ATTEMPTS - ) { - await this.messagingChannelSyncStatusService.markAsFailedUnknownAndFlushMessagesToImport( - messageChannel.id, - workspaceId, - ); + await this.handleThrottle(syncStep, messageChannel, workspaceId); + } - return; - } + private async handleFailedPrecondition( + error: GmailError, + syncStep: SyncStep, + messageChannel: ObjectRecord, + workspaceId: string, + ): Promise { + await this.messagingTelemetryService.track({ + eventName: `${snakeCase(syncStep)}.error.failed_precondition`, + workspaceId, + connectedAccountId: messageChannel.connectedAccountId, + messageChannelId: messageChannel.id, + message: `${error.code}: ${error.reason}`, + }); - await this.throttle(messageChannel, workspaceId); - - switch (syncStep) { - case 'full-message-list-fetch': - await this.messagingChannelSyncStatusService.scheduleFullMessageListFetch( - messageChannel.id, - workspaceId, - ); - break; - - case 'partial-message-list-fetch': - await this.messagingChannelSyncStatusService.schedulePartialMessageListFetch( - messageChannel.id, - workspaceId, - ); - break; - - case 'messages-import': - await this.messagingChannelSyncStatusService.scheduleMessagesImport( - messageChannel.id, - workspaceId, - ); - break; - - default: - break; - } + await this.handleThrottle(syncStep, messageChannel, workspaceId); } private async handleInsufficientPermissions( @@ -247,6 +242,51 @@ export class MessagingErrorHandlingService { ); } + private async handleThrottle( + syncStep: SyncStep, + messageChannel: ObjectRecord, + workspaceId: string, + ): Promise { + if ( + messageChannel.throttleFailureCount >= MESSAGING_THROTTLE_MAX_ATTEMPTS + ) { + await this.messagingChannelSyncStatusService.markAsFailedUnknownAndFlushMessagesToImport( + messageChannel.id, + workspaceId, + ); + + return; + } + + await this.throttle(messageChannel, workspaceId); + + switch (syncStep) { + case 'full-message-list-fetch': + await this.messagingChannelSyncStatusService.scheduleFullMessageListFetch( + messageChannel.id, + workspaceId, + ); + break; + + case 'partial-message-list-fetch': + await this.messagingChannelSyncStatusService.schedulePartialMessageListFetch( + messageChannel.id, + workspaceId, + ); + break; + + case 'messages-import': + await this.messagingChannelSyncStatusService.scheduleMessagesImport( + messageChannel.id, + workspaceId, + ); + break; + + default: + break; + } + } + private async throttle( messageChannel: ObjectRecord, workspaceId: string, @@ -264,4 +304,28 @@ export class MessagingErrorHandlingService { message: `Increment throttle failure count to ${messageChannel.throttleFailureCount}`, }); } + + private async handleUnknownError( + error: GmailError, + syncStep: SyncStep, + messageChannel: ObjectRecord, + workspaceId: string, + ): Promise { + await this.messagingTelemetryService.track({ + eventName: `${snakeCase(syncStep)}.error.unknown`, + workspaceId, + connectedAccountId: messageChannel.connectedAccountId, + messageChannelId: messageChannel.id, + message: `${error.code}: ${error.reason}`, + }); + + await this.messagingChannelSyncStatusService.markAsFailedUnknownAndFlushMessagesToImport( + messageChannel.id, + workspaceId, + ); + + throw new Error( + `Unhandled Gmail error code ${error.code} with reason ${error.reason}`, + ); + } }