Refactor error messages messaging (#16094)
We should try catch locally gmail errors when: - fetching message list - fetching messages - refreshing aliases - fetching folders
This commit is contained in:
+33
@@ -0,0 +1,33 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import {
|
||||
MessageImportDriverException,
|
||||
MessageImportDriverExceptionCode,
|
||||
} from 'src/modules/messaging/message-import-manager/drivers/exceptions/message-import-driver.exception';
|
||||
import { isGmailApiError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/is-gmail-api-error-error.util';
|
||||
import { isGmailNetworkError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/is-gmail-network-error.util';
|
||||
import { parseGmailApiError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-gmail-api-error.util';
|
||||
import { parseGmailNetworkError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-gmail-network-error.util';
|
||||
|
||||
@Injectable()
|
||||
export class GmailEmailAliasErrorHandlerService {
|
||||
private readonly logger = new Logger(GmailEmailAliasErrorHandlerService.name);
|
||||
|
||||
constructor() {}
|
||||
|
||||
public handleError(error: unknown): void {
|
||||
this.logger.error(`Google: Error getting email aliases: ${error}`);
|
||||
if (isGmailNetworkError(error)) {
|
||||
throw parseGmailNetworkError(error);
|
||||
}
|
||||
|
||||
if (isGmailApiError(error)) {
|
||||
throw parseGmailApiError(error);
|
||||
}
|
||||
|
||||
throw new MessageImportDriverException(
|
||||
'Unknown error',
|
||||
MessageImportDriverExceptionCode.UNKNOWN,
|
||||
);
|
||||
}
|
||||
}
|
||||
+10
-4
@@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { google } from 'googleapis';
|
||||
|
||||
import { GmailEmailAliasErrorHandlerService } from 'src/modules/connected-account/email-alias-manager/drivers/google/services/google-email-alias-error-handler.service';
|
||||
import { OAuth2ClientManagerService } from 'src/modules/connected-account/oauth2-client-manager/services/oauth2-client-manager.service';
|
||||
import { type ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||
|
||||
@@ -9,6 +10,7 @@ import { type ConnectedAccountWorkspaceEntity } from 'src/modules/connected-acco
|
||||
export class GoogleEmailAliasManagerService {
|
||||
constructor(
|
||||
private readonly oAuth2ClientManagerService: OAuth2ClientManagerService,
|
||||
private readonly gmailEmailAliasErrorHandlerService: GmailEmailAliasErrorHandlerService,
|
||||
) {}
|
||||
|
||||
public async getHandleAliases(
|
||||
@@ -24,10 +26,14 @@ export class GoogleEmailAliasManagerService {
|
||||
auth: oAuth2Client,
|
||||
});
|
||||
|
||||
const emailsResponse = await peopleClient.people.get({
|
||||
resourceName: 'people/me',
|
||||
personFields: 'emailAddresses',
|
||||
});
|
||||
const emailsResponse = await peopleClient.people
|
||||
.get({
|
||||
resourceName: 'people/me',
|
||||
personFields: 'emailAddresses',
|
||||
})
|
||||
.catch((error) => {
|
||||
throw this.gmailEmailAliasErrorHandlerService.handleError(error);
|
||||
});
|
||||
|
||||
const emailAddresses = emailsResponse.data.emailAddresses;
|
||||
|
||||
+4
-2
@@ -1,7 +1,8 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { GoogleEmailAliasManagerService } from 'src/modules/connected-account/email-alias-manager/drivers/google/google-email-alias-manager.service';
|
||||
import { MicrosoftEmailAliasManagerService } from 'src/modules/connected-account/email-alias-manager/drivers/microsoft/microsoft-email-alias-manager.service';
|
||||
import { GmailEmailAliasErrorHandlerService } from 'src/modules/connected-account/email-alias-manager/drivers/google/services/google-email-alias-error-handler.service';
|
||||
import { GoogleEmailAliasManagerService } from 'src/modules/connected-account/email-alias-manager/drivers/google/services/google-email-alias-manager.service';
|
||||
import { MicrosoftEmailAliasManagerService } from 'src/modules/connected-account/email-alias-manager/drivers/microsoft/services/microsoft-email-alias-manager.service';
|
||||
import { EmailAliasManagerService } from 'src/modules/connected-account/email-alias-manager/services/email-alias-manager.service';
|
||||
import { OAuth2ClientManagerModule } from 'src/modules/connected-account/oauth2-client-manager/oauth2-client-manager.module';
|
||||
|
||||
@@ -10,6 +11,7 @@ import { OAuth2ClientManagerModule } from 'src/modules/connected-account/oauth2-
|
||||
providers: [
|
||||
EmailAliasManagerService,
|
||||
GoogleEmailAliasManagerService,
|
||||
GmailEmailAliasErrorHandlerService,
|
||||
MicrosoftEmailAliasManagerService,
|
||||
],
|
||||
exports: [EmailAliasManagerService],
|
||||
|
||||
+2
-2
@@ -4,9 +4,9 @@ import { ConnectedAccountProvider } from 'twenty-shared/types';
|
||||
import { type Repository } from 'typeorm';
|
||||
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { GoogleEmailAliasManagerService } from 'src/modules/connected-account/email-alias-manager/drivers/google/google-email-alias-manager.service';
|
||||
import { MicrosoftEmailAliasManagerService } from 'src/modules/connected-account/email-alias-manager/drivers/microsoft/microsoft-email-alias-manager.service';
|
||||
import { GoogleEmailAliasManagerService } from 'src/modules/connected-account/email-alias-manager/drivers/google/services/google-email-alias-manager.service';
|
||||
import { microsoftGraphMeResponseWithProxyAddresses } from 'src/modules/connected-account/email-alias-manager/drivers/microsoft/mocks/microsoft-api-examples';
|
||||
import { MicrosoftEmailAliasManagerService } from 'src/modules/connected-account/email-alias-manager/drivers/microsoft/services/microsoft-email-alias-manager.service';
|
||||
import { OAuth2ClientManagerService } from 'src/modules/connected-account/oauth2-client-manager/services/oauth2-client-manager.service';
|
||||
import { type ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@ import { ConnectedAccountProvider } from 'twenty-shared/types';
|
||||
import { assertUnreachable } from 'twenty-shared/utils';
|
||||
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { GoogleEmailAliasManagerService } from 'src/modules/connected-account/email-alias-manager/drivers/google/google-email-alias-manager.service';
|
||||
import { MicrosoftEmailAliasManagerService } from 'src/modules/connected-account/email-alias-manager/drivers/microsoft/microsoft-email-alias-manager.service';
|
||||
import { GoogleEmailAliasManagerService } from 'src/modules/connected-account/email-alias-manager/drivers/google/services/google-email-alias-manager.service';
|
||||
import { MicrosoftEmailAliasManagerService } from 'src/modules/connected-account/email-alias-manager/drivers/microsoft/services/microsoft-email-alias-manager.service';
|
||||
import { type ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||
|
||||
@Injectable()
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ import {
|
||||
ConnectedAccountRefreshAccessTokenExceptionCode,
|
||||
} from 'src/modules/connected-account/refresh-tokens-manager/exceptions/connected-account-refresh-tokens.exception';
|
||||
import { type ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||
import { isAxiosTemporaryError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/is-axios-gaxios-error.util';
|
||||
import { isGmailNetworkError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/is-gmail-network-error.util';
|
||||
|
||||
export type ConnectedAccountTokens = {
|
||||
accessToken: string;
|
||||
@@ -142,7 +142,7 @@ export class ConnectedAccountRefreshTokensService {
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
if (isAxiosTemporaryError(error)) {
|
||||
if (isGmailNetworkError(error)) {
|
||||
throw new ConnectedAccountRefreshAccessTokenException(
|
||||
`Error refreshing tokens for connected account ${connectedAccount.id.slice(0, 7)} in workspace ${workspaceId.slice(0, 7)}: ${error.code}`,
|
||||
ConnectedAccountRefreshAccessTokenExceptionCode.TEMPORARY_NETWORK_ERROR,
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import {
|
||||
MessageImportDriverException,
|
||||
MessageImportDriverExceptionCode,
|
||||
} from 'src/modules/messaging/message-import-manager/drivers/exceptions/message-import-driver.exception';
|
||||
import { isGmailApiError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/is-gmail-api-error-error.util';
|
||||
import { isGmailNetworkError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/is-gmail-network-error.util';
|
||||
import { parseGmailApiError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-gmail-api-error.util';
|
||||
import { parseGmailNetworkError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-gmail-network-error.util';
|
||||
|
||||
@Injectable()
|
||||
export class GmailFoldersErrorHandlerService {
|
||||
private readonly logger = new Logger(GmailFoldersErrorHandlerService.name);
|
||||
|
||||
constructor() {}
|
||||
|
||||
public handleError(error: unknown): void {
|
||||
this.logger.error(`Gmail: Error fetching folders: ${error}`);
|
||||
if (isGmailNetworkError(error)) {
|
||||
throw parseGmailNetworkError(error);
|
||||
}
|
||||
|
||||
if (isGmailApiError(error)) {
|
||||
throw parseGmailApiError(error);
|
||||
}
|
||||
|
||||
throw new MessageImportDriverException(
|
||||
'Unknown error',
|
||||
MessageImportDriverExceptionCode.UNKNOWN,
|
||||
);
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -10,11 +10,11 @@ import {
|
||||
import { OAuth2ClientManagerService } from 'src/modules/connected-account/oauth2-client-manager/services/oauth2-client-manager.service';
|
||||
import { type ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
|
||||
import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||
import { GmailFoldersErrorHandlerService } from 'src/modules/messaging/message-folder-manager/drivers/gmail/services/gmail-folders-error-handler.service';
|
||||
import { extractGmailFolderName } from 'src/modules/messaging/message-folder-manager/drivers/gmail/utils/extract-gmail-folder-name.util';
|
||||
import { getGmailFolderParentId } from 'src/modules/messaging/message-folder-manager/drivers/gmail/utils/get-gmail-folder-parent-id.util';
|
||||
import { shouldSyncFolderByDefault } from 'src/modules/messaging/message-folder-manager/utils/should-sync-folder-by-default.util';
|
||||
import { MESSAGING_GMAIL_DEFAULT_NOT_SYNCED_LABELS } from 'src/modules/messaging/message-import-manager/drivers/gmail/constants/messaging-gmail-default-not-synced-labels';
|
||||
import { GmailMessageListFetchErrorHandler } from 'src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-message-list-fetch-error-handler.service';
|
||||
|
||||
@Injectable()
|
||||
export class GmailGetAllFoldersService implements MessageFolderDriver {
|
||||
@@ -22,7 +22,7 @@ export class GmailGetAllFoldersService implements MessageFolderDriver {
|
||||
|
||||
constructor(
|
||||
private readonly oAuth2ClientManagerService: OAuth2ClientManagerService,
|
||||
private readonly gmailMessageListFetchErrorHandler: GmailMessageListFetchErrorHandler,
|
||||
private readonly gmailFoldersErrorHandlerService: GmailFoldersErrorHandlerService,
|
||||
) {}
|
||||
|
||||
async getAllMessageFolders(
|
||||
@@ -53,7 +53,7 @@ export class GmailGetAllFoldersService implements MessageFolderDriver {
|
||||
`Connected account ${connectedAccount.id}: Error fetching labels: ${error.message}`,
|
||||
);
|
||||
|
||||
this.gmailMessageListFetchErrorHandler.handleError(error);
|
||||
this.gmailFoldersErrorHandlerService.handleError(error);
|
||||
|
||||
return { data: { labels: [] } };
|
||||
});
|
||||
+5
-3
@@ -6,9 +6,10 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent
|
||||
import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module';
|
||||
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
|
||||
import { OAuth2ClientManagerModule } from 'src/modules/connected-account/oauth2-client-manager/oauth2-client-manager.module';
|
||||
import { GmailGetAllFoldersService } from 'src/modules/messaging/message-folder-manager/drivers/gmail/gmail-get-all-folders.service';
|
||||
import { ImapGetAllFoldersService } from 'src/modules/messaging/message-folder-manager/drivers/imap/imap-get-all-folders.service';
|
||||
import { MicrosoftGetAllFoldersService } from 'src/modules/messaging/message-folder-manager/drivers/microsoft/microsoft-get-all-folders.service';
|
||||
import { GmailFoldersErrorHandlerService } from 'src/modules/messaging/message-folder-manager/drivers/gmail/services/gmail-folders-error-handler.service';
|
||||
import { GmailGetAllFoldersService } from 'src/modules/messaging/message-folder-manager/drivers/gmail/services/gmail-get-all-folders.service';
|
||||
import { ImapGetAllFoldersService } from 'src/modules/messaging/message-folder-manager/drivers/imap/services/imap-get-all-folders.service';
|
||||
import { MicrosoftGetAllFoldersService } from 'src/modules/messaging/message-folder-manager/drivers/microsoft/services/microsoft-get-all-folders.service';
|
||||
import { SyncMessageFoldersService } from 'src/modules/messaging/message-folder-manager/services/sync-message-folders.service';
|
||||
import { MessagingGmailDriverModule } from 'src/modules/messaging/message-import-manager/drivers/gmail/messaging-gmail-driver.module';
|
||||
import { MessagingIMAPDriverModule } from 'src/modules/messaging/message-import-manager/drivers/imap/messaging-imap-driver.module';
|
||||
@@ -28,6 +29,7 @@ import { MessagingMicrosoftDriverModule } from 'src/modules/messaging/message-im
|
||||
providers: [
|
||||
SyncMessageFoldersService,
|
||||
GmailGetAllFoldersService,
|
||||
GmailFoldersErrorHandlerService,
|
||||
ImapGetAllFoldersService,
|
||||
MicrosoftGetAllFoldersService,
|
||||
],
|
||||
|
||||
+3
-3
@@ -14,9 +14,9 @@ import {
|
||||
MessageFolderPendingSyncAction,
|
||||
type MessageFolderWorkspaceEntity,
|
||||
} from 'src/modules/messaging/common/standard-objects/message-folder.workspace-entity';
|
||||
import { GmailGetAllFoldersService } from 'src/modules/messaging/message-folder-manager/drivers/gmail/gmail-get-all-folders.service';
|
||||
import { ImapGetAllFoldersService } from 'src/modules/messaging/message-folder-manager/drivers/imap/imap-get-all-folders.service';
|
||||
import { MicrosoftGetAllFoldersService } from 'src/modules/messaging/message-folder-manager/drivers/microsoft/microsoft-get-all-folders.service';
|
||||
import { GmailGetAllFoldersService } from 'src/modules/messaging/message-folder-manager/drivers/gmail/services/gmail-get-all-folders.service';
|
||||
import { ImapGetAllFoldersService } from 'src/modules/messaging/message-folder-manager/drivers/imap/services/imap-get-all-folders.service';
|
||||
import { MicrosoftGetAllFoldersService } from 'src/modules/messaging/message-folder-manager/drivers/microsoft/services/microsoft-get-all-folders.service';
|
||||
import { MessageFolderName } from 'src/modules/messaging/message-import-manager/drivers/microsoft/types/folders';
|
||||
|
||||
type SyncMessageFoldersInput = {
|
||||
|
||||
-3
@@ -17,7 +17,6 @@ import { GmailGetMessageListService } from 'src/modules/messaging/message-import
|
||||
import { GmailGetMessagesService } from 'src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-get-messages.service';
|
||||
import { GmailMessageListFetchErrorHandler } from 'src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-message-list-fetch-error-handler.service';
|
||||
import { GmailMessagesImportErrorHandler } from 'src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-messages-import-error-handler.service';
|
||||
import { GmailNetworkErrorHandler } from 'src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-network-error-handler.service';
|
||||
import { MessageParticipantManagerModule } from 'src/modules/messaging/message-participant-manager/message-participant-manager.module';
|
||||
|
||||
@Module({
|
||||
@@ -40,14 +39,12 @@ import { MessageParticipantManagerModule } from 'src/modules/messaging/message-p
|
||||
GmailFetchByBatchService,
|
||||
GmailGetMessagesService,
|
||||
GmailGetMessageListService,
|
||||
GmailNetworkErrorHandler,
|
||||
GmailMessageListFetchErrorHandler,
|
||||
GmailMessagesImportErrorHandler,
|
||||
],
|
||||
exports: [
|
||||
GmailGetMessagesService,
|
||||
GmailGetMessageListService,
|
||||
GmailNetworkErrorHandler,
|
||||
GmailMessageListFetchErrorHandler,
|
||||
GmailMessagesImportErrorHandler,
|
||||
],
|
||||
|
||||
+27
-153
@@ -1,196 +1,70 @@
|
||||
// Gmail API Error Response Mocks for users.messages.list
|
||||
import { type GmailApiError } from 'src/modules/messaging/message-import-manager/drivers/gmail/types/gmail-api-error.type';
|
||||
|
||||
const gmailApiErrorMocks = {
|
||||
// 400 Bad Request - Invalid query parameters
|
||||
badRequest: {
|
||||
error: {
|
||||
code: 400,
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
location: 'orderBy',
|
||||
locationType: 'parameter',
|
||||
message:
|
||||
'Sorting is not supported for queries with fullText terms. Results are always in descending relevance order.',
|
||||
reason: 'badRequest',
|
||||
},
|
||||
],
|
||||
message:
|
||||
'Sorting is not supported for queries with fullText terms. Results are always in descending relevance order.',
|
||||
},
|
||||
code: '400',
|
||||
message: 'badRequest',
|
||||
},
|
||||
|
||||
// 400 Invalid Grant
|
||||
invalidGrant: {
|
||||
error: {
|
||||
code: 400,
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'invalid_grant',
|
||||
message: 'Invalid Credentials',
|
||||
},
|
||||
],
|
||||
message: 'Invalid Credentials',
|
||||
},
|
||||
code: '400',
|
||||
message: 'invalid_grant',
|
||||
},
|
||||
|
||||
// 400 Failed Precondition
|
||||
failedPrecondition: {
|
||||
error: {
|
||||
code: 400,
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'failedPrecondition',
|
||||
message: 'Failed Precondition',
|
||||
},
|
||||
],
|
||||
message: 'Failed Precondition',
|
||||
},
|
||||
code: '400',
|
||||
message: 'failedPrecondition',
|
||||
},
|
||||
|
||||
// 401 Invalid Credentials
|
||||
invalidCredentials: {
|
||||
error: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'authError',
|
||||
message: 'Invalid Credentials',
|
||||
locationType: 'header',
|
||||
location: 'Authorization',
|
||||
},
|
||||
],
|
||||
code: 401,
|
||||
message: 'Invalid Credentials',
|
||||
},
|
||||
code: '401',
|
||||
message: 'authError',
|
||||
},
|
||||
|
||||
// 404 Not Found
|
||||
notFound: {
|
||||
error: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'notFound',
|
||||
message: 'Resource not found: userId',
|
||||
location: 'userId',
|
||||
locationType: 'parameter',
|
||||
},
|
||||
],
|
||||
code: 404,
|
||||
message: 'Resource not found: userId',
|
||||
},
|
||||
code: '404',
|
||||
message: 'notFound',
|
||||
},
|
||||
|
||||
// 410 Gone
|
||||
gone: {
|
||||
error: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'resourceGone',
|
||||
message: 'Resource has been deleted',
|
||||
location: 'messageId',
|
||||
locationType: 'parameter',
|
||||
},
|
||||
],
|
||||
code: 410,
|
||||
message: 'Resource has been deleted',
|
||||
},
|
||||
code: '410',
|
||||
message: 'resourceGone',
|
||||
},
|
||||
|
||||
// 403 Daily Limit Exceeded
|
||||
dailyLimitExceeded: {
|
||||
error: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'usageLimits',
|
||||
reason: 'dailyLimitExceeded',
|
||||
message: 'Daily Limit Exceeded',
|
||||
},
|
||||
],
|
||||
code: 403,
|
||||
message: 'Daily Limit Exceeded',
|
||||
},
|
||||
code: '403',
|
||||
message: 'dailyLimitExceeded',
|
||||
},
|
||||
|
||||
// 403 User Rate Limit Exceeded
|
||||
userRateLimitExceeded: {
|
||||
error: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'usageLimits',
|
||||
reason: 'userRateLimitExceeded',
|
||||
message: 'User Rate Limit Exceeded',
|
||||
},
|
||||
],
|
||||
code: 403,
|
||||
message: 'User Rate Limit Exceeded',
|
||||
},
|
||||
code: '403',
|
||||
message: 'userRateLimitExceeded',
|
||||
},
|
||||
|
||||
// 403 Rate Limit Exceeded
|
||||
rateLimitExceeded: {
|
||||
error: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'usageLimits',
|
||||
reason: 'rateLimitExceeded',
|
||||
message: 'Rate Limit Exceeded',
|
||||
},
|
||||
],
|
||||
code: 403,
|
||||
message: 'Rate Limit Exceeded',
|
||||
},
|
||||
code: '403',
|
||||
message: 'rateLimitExceeded',
|
||||
},
|
||||
|
||||
// 403 Domain Policy Error
|
||||
domainPolicyError: {
|
||||
error: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'domainPolicy',
|
||||
message: 'The domain administrators have disabled Gmail apps.',
|
||||
},
|
||||
],
|
||||
code: 403,
|
||||
message: 'The domain administrators have disabled Gmail apps.',
|
||||
},
|
||||
code: '403',
|
||||
message: 'domainPolicy',
|
||||
},
|
||||
|
||||
// 429 Too Many Requests (Concurrent Requests)
|
||||
tooManyConcurrentRequests: {
|
||||
error: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'rateLimitExceeded',
|
||||
message: 'Too many concurrent requests for user',
|
||||
},
|
||||
],
|
||||
code: 429,
|
||||
message: 'Too many concurrent requests for user',
|
||||
},
|
||||
code: '429',
|
||||
message: 'tooManyConcurrentRequests',
|
||||
},
|
||||
|
||||
// 500 Backend Error
|
||||
backendError: {
|
||||
error: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'backendError',
|
||||
message: 'Backend Error',
|
||||
},
|
||||
],
|
||||
code: 500,
|
||||
message: 'Backend Error',
|
||||
},
|
||||
code: '500',
|
||||
message: 'backendError',
|
||||
},
|
||||
|
||||
getError: function (code: number, type?: string) {
|
||||
getError: function (code: number, type?: string): GmailApiError {
|
||||
switch (code) {
|
||||
case 400:
|
||||
switch (type) {
|
||||
|
||||
+217
@@ -0,0 +1,217 @@
|
||||
import { type GmailApiBatchError } from 'src/modules/messaging/message-import-manager/drivers/gmail/types/gmail-api-batch-error.type';
|
||||
|
||||
const gmailBatchApiErrorMocks = {
|
||||
// 400 Bad Request - Invalid query parameters
|
||||
badRequest: {
|
||||
code: 400,
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
location: 'orderBy',
|
||||
locationType: 'parameter',
|
||||
message:
|
||||
'Sorting is not supported for queries with fullText terms. Results are always in descending relevance order.',
|
||||
reason: 'badRequest',
|
||||
},
|
||||
],
|
||||
message:
|
||||
'Sorting is not supported for queries with fullText terms. Results are always in descending relevance order.',
|
||||
},
|
||||
|
||||
// 400 Invalid Grant
|
||||
invalidGrant: {
|
||||
code: 400,
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'invalid_grant',
|
||||
message: 'Invalid Credentials',
|
||||
},
|
||||
],
|
||||
message: 'Invalid Credentials',
|
||||
},
|
||||
|
||||
// 400 Failed Precondition
|
||||
failedPrecondition: {
|
||||
code: 400,
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'failedPrecondition',
|
||||
message: 'Failed Precondition',
|
||||
},
|
||||
],
|
||||
message: 'Failed Precondition',
|
||||
},
|
||||
|
||||
// 401 Invalid Credentials
|
||||
invalidCredentials: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'authError',
|
||||
message: 'Invalid Credentials',
|
||||
locationType: 'header',
|
||||
location: 'Authorization',
|
||||
},
|
||||
],
|
||||
code: 401,
|
||||
message: 'Invalid Credentials',
|
||||
},
|
||||
|
||||
// 404 Not Found
|
||||
notFound: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'notFound',
|
||||
message: 'Resource not found: userId',
|
||||
location: 'userId',
|
||||
locationType: 'parameter',
|
||||
},
|
||||
],
|
||||
code: 404,
|
||||
message: 'Resource not found: userId',
|
||||
},
|
||||
|
||||
// 410 Gone
|
||||
gone: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'resourceGone',
|
||||
message: 'Resource has been deleted',
|
||||
location: 'messageId',
|
||||
locationType: 'parameter',
|
||||
},
|
||||
],
|
||||
code: 410,
|
||||
message: 'Resource has been deleted',
|
||||
},
|
||||
|
||||
// 403 Daily Limit Exceeded
|
||||
dailyLimitExceeded: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'usageLimits',
|
||||
reason: 'dailyLimitExceeded',
|
||||
message: 'Daily Limit Exceeded',
|
||||
},
|
||||
],
|
||||
code: 403,
|
||||
message: 'Daily Limit Exceeded',
|
||||
},
|
||||
|
||||
// 403 User Rate Limit Exceeded
|
||||
userRateLimitExceeded: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'usageLimits',
|
||||
reason: 'userRateLimitExceeded',
|
||||
message: 'User Rate Limit Exceeded',
|
||||
},
|
||||
],
|
||||
code: 403,
|
||||
message: 'User Rate Limit Exceeded',
|
||||
},
|
||||
|
||||
// 403 Rate Limit Exceeded
|
||||
rateLimitExceeded: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'usageLimits',
|
||||
reason: 'rateLimitExceeded',
|
||||
message: 'Rate Limit Exceeded',
|
||||
},
|
||||
],
|
||||
code: 403,
|
||||
message: 'Rate Limit Exceeded',
|
||||
},
|
||||
|
||||
// 403 Domain Policy Error
|
||||
domainPolicyError: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'domainPolicy',
|
||||
message: 'The domain administrators have disabled Gmail apps.',
|
||||
},
|
||||
],
|
||||
code: 403,
|
||||
message: 'The domain administrators have disabled Gmail apps.',
|
||||
},
|
||||
|
||||
// 429 Too Many Requests (Concurrent Requests)
|
||||
tooManyConcurrentRequests: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'rateLimitExceeded',
|
||||
message: 'Too many concurrent requests for user',
|
||||
},
|
||||
],
|
||||
code: 429,
|
||||
message: 'Too many concurrent requests for user',
|
||||
},
|
||||
|
||||
// 500 Backend Error
|
||||
backendError: {
|
||||
errors: [
|
||||
{
|
||||
domain: 'global',
|
||||
reason: 'backendError',
|
||||
message: 'Backend Error',
|
||||
},
|
||||
],
|
||||
code: 500,
|
||||
message: 'Backend Error',
|
||||
},
|
||||
|
||||
getError: function (code: number, type?: string): GmailApiBatchError {
|
||||
switch (code) {
|
||||
case 400:
|
||||
switch (type) {
|
||||
case 'invalid_grant':
|
||||
return this.invalidGrant;
|
||||
case 'failedPrecondition':
|
||||
return this.failedPrecondition;
|
||||
default:
|
||||
return this.badRequest;
|
||||
}
|
||||
case 401:
|
||||
return this.invalidCredentials;
|
||||
case 403:
|
||||
switch (type) {
|
||||
case 'dailyLimit':
|
||||
return this.dailyLimitExceeded;
|
||||
case 'userRateLimit':
|
||||
return this.userRateLimitExceeded;
|
||||
case 'rateLimit':
|
||||
return this.rateLimitExceeded;
|
||||
case 'domainPolicy':
|
||||
return this.domainPolicyError;
|
||||
default:
|
||||
return this.rateLimitExceeded;
|
||||
}
|
||||
case 404:
|
||||
return this.notFound;
|
||||
case 410:
|
||||
return this.gone;
|
||||
case 429:
|
||||
switch (type) {
|
||||
case 'concurrent':
|
||||
return this.tooManyConcurrentRequests;
|
||||
case 'mailSending':
|
||||
return this.mailSendingLimitExceeded;
|
||||
default:
|
||||
return this.tooManyConcurrentRequests;
|
||||
}
|
||||
case 500:
|
||||
return this.backendError;
|
||||
default:
|
||||
throw new Error(`Unknown error code: ${code}`);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default gmailBatchApiErrorMocks;
|
||||
+21
-14
@@ -1,26 +1,33 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { GmailNetworkErrorHandler } from 'src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-network-error-handler.service';
|
||||
import { parseGmailMessageListFetchError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-gmail-message-list-fetch-error.util';
|
||||
import {
|
||||
MessageImportDriverException,
|
||||
MessageImportDriverExceptionCode,
|
||||
} from 'src/modules/messaging/message-import-manager/drivers/exceptions/message-import-driver.exception';
|
||||
import { isGmailApiError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/is-gmail-api-error-error.util';
|
||||
import { isGmailNetworkError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/is-gmail-network-error.util';
|
||||
import { parseGmailApiError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-gmail-api-error.util';
|
||||
import { parseGmailNetworkError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-gmail-network-error.util';
|
||||
|
||||
@Injectable()
|
||||
export class GmailMessageListFetchErrorHandler {
|
||||
private readonly logger = new Logger(GmailMessageListFetchErrorHandler.name);
|
||||
|
||||
constructor(
|
||||
private readonly gmailNetworkErrorHandler: GmailNetworkErrorHandler,
|
||||
) {}
|
||||
constructor() {}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
public handleError(error: any): void {
|
||||
this.logger.log(`Error fetching message list`, error);
|
||||
|
||||
const networkError = this.gmailNetworkErrorHandler.handleError(error);
|
||||
|
||||
if (networkError) {
|
||||
throw networkError;
|
||||
public handleError(error: unknown): void {
|
||||
this.logger.error(`Gmail: Error fetching message list: ${error}`);
|
||||
if (isGmailNetworkError(error)) {
|
||||
throw parseGmailNetworkError(error);
|
||||
}
|
||||
|
||||
throw parseGmailMessageListFetchError(error, { cause: error });
|
||||
if (isGmailApiError(error)) {
|
||||
throw parseGmailApiError(error);
|
||||
}
|
||||
|
||||
throw new MessageImportDriverException(
|
||||
'Unknown error',
|
||||
MessageImportDriverExceptionCode.UNKNOWN,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+20
-18
@@ -1,32 +1,34 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { GmailNetworkErrorHandler } from 'src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-network-error-handler.service';
|
||||
import { parseGmailMessagesImportError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-gmail-messages-import-error.util';
|
||||
import {
|
||||
MessageImportDriverException,
|
||||
MessageImportDriverExceptionCode,
|
||||
} from 'src/modules/messaging/message-import-manager/drivers/exceptions/message-import-driver.exception';
|
||||
import { isGmailApiBatchError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/is-gmail-api-batch-error.util';
|
||||
import { isGmailNetworkError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/is-gmail-network-error.util';
|
||||
import { parseGmailApiBatchError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-gmail-api-batch-error.util';
|
||||
import { parseGmailNetworkError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-gmail-network-error.util';
|
||||
|
||||
@Injectable()
|
||||
export class GmailMessagesImportErrorHandler {
|
||||
private readonly logger = new Logger(GmailMessagesImportErrorHandler.name);
|
||||
|
||||
constructor(
|
||||
private readonly gmailNetworkErrorHandler: GmailNetworkErrorHandler,
|
||||
) {}
|
||||
constructor() {}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
public handleError(error: any, messageExternalId: string): void {
|
||||
this.logger.log(`Error fetching messages`, error);
|
||||
public handleError(error: unknown, messageExternalId: string): void {
|
||||
this.logger.error(`Gmail: Error importing messages: ${error}`);
|
||||
|
||||
const networkError = this.gmailNetworkErrorHandler.handleError(error);
|
||||
|
||||
if (networkError) {
|
||||
throw networkError;
|
||||
if (isGmailNetworkError(error)) {
|
||||
throw parseGmailNetworkError(error);
|
||||
}
|
||||
|
||||
const gmailError = parseGmailMessagesImportError(error, messageExternalId, {
|
||||
cause: error,
|
||||
});
|
||||
|
||||
if (gmailError) {
|
||||
throw gmailError;
|
||||
if (isGmailApiBatchError(error)) {
|
||||
throw parseGmailApiBatchError(error, messageExternalId);
|
||||
}
|
||||
|
||||
throw new MessageImportDriverException(
|
||||
'Unknown error',
|
||||
MessageImportDriverExceptionCode.UNKNOWN,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import {
|
||||
MessageImportDriverException,
|
||||
MessageImportDriverExceptionCode,
|
||||
} from 'src/modules/messaging/message-import-manager/drivers/exceptions/message-import-driver.exception';
|
||||
import { isAxiosTemporaryError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/is-axios-gaxios-error.util';
|
||||
|
||||
@Injectable()
|
||||
export class GmailNetworkErrorHandler {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
public handleError(error: any): MessageImportDriverException | null {
|
||||
if (isAxiosTemporaryError(error)) {
|
||||
return new MessageImportDriverException(
|
||||
error.message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
{ cause: error },
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
export type GmailApiBatchError = {
|
||||
code: number;
|
||||
errors: {
|
||||
reason: string;
|
||||
message: string;
|
||||
}[];
|
||||
};
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
export type GmailApiError = {
|
||||
code: string;
|
||||
message: string;
|
||||
};
|
||||
+8
-8
@@ -1,45 +1,45 @@
|
||||
import gaxiosErrorMocks from 'src/modules/messaging/message-import-manager/drivers/gmail/mocks/gaxios-error-mocks';
|
||||
import { isAxiosTemporaryError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/is-axios-gaxios-error.util';
|
||||
import { isGmailNetworkError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/is-gmail-network-error.util';
|
||||
|
||||
describe('parseGaxiosError', () => {
|
||||
describe('isGmailNetworkError', () => {
|
||||
it('should return a MessageImportDriverException for ECONNRESET', () => {
|
||||
const error = gaxiosErrorMocks.getError('ECONNRESET');
|
||||
const result = isAxiosTemporaryError(error);
|
||||
const result = isGmailNetworkError(error);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return a MessageImportDriverException for ENOTFOUND', () => {
|
||||
const error = gaxiosErrorMocks.getError('ENOTFOUND');
|
||||
const result = isAxiosTemporaryError(error);
|
||||
const result = isGmailNetworkError(error);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return a MessageImportDriverException for ECONNABORTED', () => {
|
||||
const error = gaxiosErrorMocks.getError('ECONNABORTED');
|
||||
const result = isAxiosTemporaryError(error);
|
||||
const result = isGmailNetworkError(error);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return a MessageImportDriverException for ETIMEDOUT', () => {
|
||||
const error = gaxiosErrorMocks.getError('ETIMEDOUT');
|
||||
const result = isAxiosTemporaryError(error);
|
||||
const result = isGmailNetworkError(error);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return a MessageImportDriverException for ERR_NETWORK', () => {
|
||||
const error = gaxiosErrorMocks.getError('ERR_NETWORK');
|
||||
const result = isAxiosTemporaryError(error);
|
||||
const result = isGmailNetworkError(error);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return undefined for unknown error codes', () => {
|
||||
const error = { code: 'UNKNOWN_ERROR' } as any;
|
||||
const result = isAxiosTemporaryError(error);
|
||||
const result = isGmailNetworkError(error);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
+14
-14
@@ -3,12 +3,12 @@ import {
|
||||
MessageImportDriverExceptionCode,
|
||||
} from 'src/modules/messaging/message-import-manager/drivers/exceptions/message-import-driver.exception';
|
||||
import gmailApiErrorMocks from 'src/modules/messaging/message-import-manager/drivers/gmail/mocks/gmail-api-error-mocks';
|
||||
import { parseGmailMessageListFetchError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-gmail-message-list-fetch-error.util';
|
||||
import { parseGmailApiError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-gmail-api-error.util';
|
||||
|
||||
describe('parseGmailMessageListFetchError', () => {
|
||||
describe('parseGmailApiError', () => {
|
||||
it('should handle 400 Bad Request', () => {
|
||||
const error = gmailApiErrorMocks.getError(400);
|
||||
const exception = parseGmailMessageListFetchError(error.error);
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception.code).toBe(MessageImportDriverExceptionCode.UNKNOWN);
|
||||
@@ -16,7 +16,7 @@ describe('parseGmailMessageListFetchError', () => {
|
||||
|
||||
it('should handle 400 Invalid Grant', () => {
|
||||
const error = gmailApiErrorMocks.getError(400, 'invalid_grant');
|
||||
const exception = parseGmailMessageListFetchError(error.error);
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception.code).toBe(
|
||||
@@ -26,7 +26,7 @@ describe('parseGmailMessageListFetchError', () => {
|
||||
|
||||
it('should handle 400 Failed Precondition', () => {
|
||||
const error = gmailApiErrorMocks.getError(400, 'failedPrecondition');
|
||||
const exception = parseGmailMessageListFetchError(error.error);
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception.code).toBe(
|
||||
@@ -36,7 +36,7 @@ describe('parseGmailMessageListFetchError', () => {
|
||||
|
||||
it('should handle 401 Invalid Credentials', () => {
|
||||
const error = gmailApiErrorMocks.getError(401);
|
||||
const exception = parseGmailMessageListFetchError(error.error);
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception.code).toBe(
|
||||
@@ -46,7 +46,7 @@ describe('parseGmailMessageListFetchError', () => {
|
||||
|
||||
it('should handle 403 Daily Limit Exceeded', () => {
|
||||
const error = gmailApiErrorMocks.getError(403, 'dailyLimit');
|
||||
const exception = parseGmailMessageListFetchError(error.error);
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception.code).toBe(
|
||||
@@ -56,7 +56,7 @@ describe('parseGmailMessageListFetchError', () => {
|
||||
|
||||
it('should handle 403 User Rate Limit Exceeded', () => {
|
||||
const error = gmailApiErrorMocks.getError(403, 'userRateLimit');
|
||||
const exception = parseGmailMessageListFetchError(error.error);
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception.code).toBe(
|
||||
@@ -66,7 +66,7 @@ describe('parseGmailMessageListFetchError', () => {
|
||||
|
||||
it('should handle 403 Rate Limit Exceeded', () => {
|
||||
const error = gmailApiErrorMocks.getError(403, 'rateLimit');
|
||||
const exception = parseGmailMessageListFetchError(error.error);
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception.code).toBe(
|
||||
@@ -76,7 +76,7 @@ describe('parseGmailMessageListFetchError', () => {
|
||||
|
||||
it('should handle 403 Domain Policy Error', () => {
|
||||
const error = gmailApiErrorMocks.getError(403, 'domainPolicy');
|
||||
const exception = parseGmailMessageListFetchError(error.error);
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception.code).toBe(
|
||||
@@ -86,7 +86,7 @@ describe('parseGmailMessageListFetchError', () => {
|
||||
|
||||
it('should handle 404 as sync cursor error', () => {
|
||||
const error = gmailApiErrorMocks.getError(404);
|
||||
const exception = parseGmailMessageListFetchError(error.error);
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception.code).toBe(
|
||||
@@ -96,7 +96,7 @@ describe('parseGmailMessageListFetchError', () => {
|
||||
|
||||
it('should handle 410 Gone', () => {
|
||||
const error = gmailApiErrorMocks.getError(410);
|
||||
const exception = parseGmailMessageListFetchError(error.error);
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception.code).toBe(MessageImportDriverExceptionCode.UNKNOWN);
|
||||
@@ -104,7 +104,7 @@ describe('parseGmailMessageListFetchError', () => {
|
||||
|
||||
it('should handle 429 Too Many Requests', () => {
|
||||
const error = gmailApiErrorMocks.getError(429, 'concurrent');
|
||||
const exception = parseGmailMessageListFetchError(error.error);
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception.code).toBe(
|
||||
@@ -114,7 +114,7 @@ describe('parseGmailMessageListFetchError', () => {
|
||||
|
||||
it('should handle 500 Backend Error', () => {
|
||||
const error = gmailApiErrorMocks.getError(500);
|
||||
const exception = parseGmailMessageListFetchError(error.error);
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception.code).toBe(
|
||||
|
||||
+38
-74
@@ -2,48 +2,39 @@ import {
|
||||
MessageImportDriverException,
|
||||
MessageImportDriverExceptionCode,
|
||||
} from 'src/modules/messaging/message-import-manager/drivers/exceptions/message-import-driver.exception';
|
||||
import gmailApiErrorMocks from 'src/modules/messaging/message-import-manager/drivers/gmail/mocks/gmail-api-error-mocks';
|
||||
import { parseGmailMessagesImportError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-gmail-messages-import-error.util';
|
||||
import { default as gmailBatchApiErrorMocks } from 'src/modules/messaging/message-import-manager/drivers/gmail/mocks/gmail-batch-api-error-mocks';
|
||||
import { parseGmailApiBatchError } from 'src/modules/messaging/message-import-manager/drivers/gmail/utils/parse-gmail-api-batch-error.util';
|
||||
|
||||
const messageExternalId = '123';
|
||||
|
||||
describe('parseGmailMessagesImportError', () => {
|
||||
describe('parseGmailApiBatchError', () => {
|
||||
it('should handle 400 Bad Request', () => {
|
||||
const error = gmailApiErrorMocks.getError(400);
|
||||
const exception = parseGmailMessagesImportError(
|
||||
error.error,
|
||||
messageExternalId,
|
||||
);
|
||||
const error = gmailBatchApiErrorMocks.getError(400);
|
||||
const exception = parseGmailApiBatchError(error, messageExternalId);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception?.code).toBe(MessageImportDriverExceptionCode.UNKNOWN);
|
||||
expect(exception?.message).toBe(
|
||||
`${error.error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
`${error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle 400 Invalid Grant', () => {
|
||||
const error = gmailApiErrorMocks.getError(400, 'invalid_grant');
|
||||
const exception = parseGmailMessagesImportError(
|
||||
error.error,
|
||||
messageExternalId,
|
||||
);
|
||||
const error = gmailBatchApiErrorMocks.getError(400, 'invalid_grant');
|
||||
const exception = parseGmailApiBatchError(error, messageExternalId);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception?.code).toBe(
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
);
|
||||
expect(exception?.message).toBe(
|
||||
`${error.error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
`${error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle 400 Failed Precondition', () => {
|
||||
const error = gmailApiErrorMocks.getError(400, 'failedPrecondition');
|
||||
const exception = parseGmailMessagesImportError(
|
||||
error.error,
|
||||
messageExternalId,
|
||||
);
|
||||
const error = gmailBatchApiErrorMocks.getError(400, 'failedPrecondition');
|
||||
const exception = parseGmailApiBatchError(error, messageExternalId);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception?.code).toBe(
|
||||
@@ -52,146 +43,119 @@ describe('parseGmailMessagesImportError', () => {
|
||||
});
|
||||
|
||||
it('should handle 401 Invalid Credentials', () => {
|
||||
const error = gmailApiErrorMocks.getError(401);
|
||||
const exception = parseGmailMessagesImportError(
|
||||
error.error,
|
||||
messageExternalId,
|
||||
);
|
||||
const error = gmailBatchApiErrorMocks.getError(401);
|
||||
const exception = parseGmailApiBatchError(error, messageExternalId);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception?.code).toBe(
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
);
|
||||
expect(exception?.message).toBe(
|
||||
`${error.error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
`${error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle 403 Daily Limit Exceeded', () => {
|
||||
const error = gmailApiErrorMocks.getError(403, 'dailyLimit');
|
||||
const exception = parseGmailMessagesImportError(
|
||||
error.error,
|
||||
messageExternalId,
|
||||
);
|
||||
const error = gmailBatchApiErrorMocks.getError(403, 'dailyLimit');
|
||||
const exception = parseGmailApiBatchError(error, messageExternalId);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception?.code).toBe(
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
);
|
||||
expect(exception?.message).toBe(
|
||||
`${error.error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
`${error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle 403 User Rate Limit Exceeded', () => {
|
||||
const error = gmailApiErrorMocks.getError(403, 'userRateLimit');
|
||||
const exception = parseGmailMessagesImportError(
|
||||
error.error,
|
||||
messageExternalId,
|
||||
);
|
||||
const error = gmailBatchApiErrorMocks.getError(403, 'userRateLimit');
|
||||
const exception = parseGmailApiBatchError(error, messageExternalId);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception?.code).toBe(
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
);
|
||||
expect(exception?.message).toBe(
|
||||
`${error.error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
`${error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle 403 Rate Limit Exceeded', () => {
|
||||
const error = gmailApiErrorMocks.getError(403, 'rateLimit');
|
||||
const exception = parseGmailMessagesImportError(
|
||||
error.error,
|
||||
messageExternalId,
|
||||
);
|
||||
const error = gmailBatchApiErrorMocks.getError(403, 'rateLimit');
|
||||
const exception = parseGmailApiBatchError(error, messageExternalId);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception?.code).toBe(
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
);
|
||||
expect(exception?.message).toBe(
|
||||
`${error.error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
`${error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle 403 Domain Policy Error', () => {
|
||||
const error = gmailApiErrorMocks.getError(403, 'domainPolicy');
|
||||
const exception = parseGmailMessagesImportError(
|
||||
error.error,
|
||||
messageExternalId,
|
||||
);
|
||||
const error = gmailBatchApiErrorMocks.getError(403, 'domainPolicy');
|
||||
const exception = parseGmailApiBatchError(error, messageExternalId);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception?.code).toBe(
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
);
|
||||
expect(exception?.message).toBe(
|
||||
`${error.error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
`${error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle 404 Not Found', () => {
|
||||
const error = gmailApiErrorMocks.getError(404);
|
||||
const exception = parseGmailMessagesImportError(
|
||||
error.error,
|
||||
messageExternalId,
|
||||
);
|
||||
const error = gmailBatchApiErrorMocks.getError(404);
|
||||
const exception = parseGmailApiBatchError(error, messageExternalId);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception?.code).toBe(
|
||||
MessageImportDriverExceptionCode.SYNC_CURSOR_ERROR,
|
||||
);
|
||||
expect(exception?.message).toBe(
|
||||
`${error.error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
`${error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle 410 Gone', () => {
|
||||
const error = gmailApiErrorMocks.getError(410);
|
||||
const exception = parseGmailMessagesImportError(
|
||||
error.error,
|
||||
messageExternalId,
|
||||
);
|
||||
const error = gmailBatchApiErrorMocks.getError(410);
|
||||
const exception = parseGmailApiBatchError(error, messageExternalId);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception?.code).toBe(
|
||||
MessageImportDriverExceptionCode.SYNC_CURSOR_ERROR,
|
||||
);
|
||||
expect(exception?.message).toBe(
|
||||
`${error.error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
`${error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle 429 Too Many Requests', () => {
|
||||
const error = gmailApiErrorMocks.getError(429, 'concurrent');
|
||||
const exception = parseGmailMessagesImportError(
|
||||
error.error,
|
||||
messageExternalId,
|
||||
);
|
||||
const error = gmailBatchApiErrorMocks.getError(429, 'concurrent');
|
||||
const exception = parseGmailApiBatchError(error, messageExternalId);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception?.code).toBe(
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
);
|
||||
expect(exception?.message).toBe(
|
||||
`${error.error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
`${error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle 500 Backend Error', () => {
|
||||
const error = gmailApiErrorMocks.getError(500);
|
||||
const exception = parseGmailMessagesImportError(
|
||||
error.error,
|
||||
messageExternalId,
|
||||
);
|
||||
const error = gmailBatchApiErrorMocks.getError(500);
|
||||
const exception = parseGmailApiBatchError(error, messageExternalId);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception?.code).toBe(
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
);
|
||||
expect(exception?.message).toBe(
|
||||
`${error.error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
`${error.errors[0].message} for message with externalId: ${messageExternalId}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import { type GmailApiBatchError } from 'src/modules/messaging/message-import-manager/drivers/gmail/types/gmail-api-batch-error.type';
|
||||
|
||||
export const isGmailApiBatchError = (
|
||||
error: unknown,
|
||||
): error is GmailApiBatchError => {
|
||||
if (error === null || typeof error !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!('code' in error) ||
|
||||
!('errors' in error) ||
|
||||
!Array.isArray(error.errors) ||
|
||||
error.errors.length === 0 ||
|
||||
error.errors.some((error) => !('reason' in error) || !('message' in error))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import { type GmailApiError } from 'src/modules/messaging/message-import-manager/drivers/gmail/types/gmail-api-error.type';
|
||||
|
||||
export const isGmailApiError = (error: unknown): error is GmailApiError => {
|
||||
if (error === null || typeof error !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!('code' in error) ||
|
||||
typeof error.code !== 'string' ||
|
||||
!('message' in error) ||
|
||||
typeof error.message !== 'string'
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
+9
-4
@@ -2,10 +2,16 @@ import { type GaxiosError } from 'gaxios';
|
||||
|
||||
import { MessageNetworkExceptionCode } from 'src/modules/messaging/message-import-manager/drivers/exceptions/message-network.exception';
|
||||
|
||||
export const isAxiosTemporaryError = (error: GaxiosError): boolean => {
|
||||
const { code } = error;
|
||||
export const isGmailNetworkError = (error: unknown): error is GaxiosError => {
|
||||
if (error === null || typeof error !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
if (!('code' in error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (error.code) {
|
||||
case MessageNetworkExceptionCode.ECONNRESET:
|
||||
case MessageNetworkExceptionCode.ENOTFOUND:
|
||||
case MessageNetworkExceptionCode.ECONNABORTED:
|
||||
@@ -13,7 +19,6 @@ export const isAxiosTemporaryError = (error: GaxiosError): boolean => {
|
||||
case MessageNetworkExceptionCode.ERR_NETWORK:
|
||||
case MessageNetworkExceptionCode.EHOSTUNREACH:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
+4
-23
@@ -2,17 +2,11 @@ import {
|
||||
MessageImportDriverException,
|
||||
MessageImportDriverExceptionCode,
|
||||
} from 'src/modules/messaging/message-import-manager/drivers/exceptions/message-import-driver.exception';
|
||||
import { type GmailApiBatchError } from 'src/modules/messaging/message-import-manager/drivers/gmail/types/gmail-api-batch-error.type';
|
||||
|
||||
export const parseGmailMessagesImportError = (
|
||||
error: {
|
||||
code?: number;
|
||||
errors: {
|
||||
reason: string;
|
||||
message: string;
|
||||
}[];
|
||||
},
|
||||
messageExternalId: string,
|
||||
options?: { cause?: Error },
|
||||
export const parseGmailApiBatchError = (
|
||||
error: GmailApiBatchError,
|
||||
messageExternalId?: string,
|
||||
): MessageImportDriverException | undefined => {
|
||||
const { code, errors } = error;
|
||||
|
||||
@@ -26,7 +20,6 @@ export const parseGmailMessagesImportError = (
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
}
|
||||
if (reason === 'failedPrecondition') {
|
||||
@@ -34,21 +27,18 @@ export const parseGmailMessagesImportError = (
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
}
|
||||
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
}
|
||||
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.UNKNOWN,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
|
||||
case 404:
|
||||
@@ -56,14 +46,12 @@ export const parseGmailMessagesImportError = (
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.SYNC_CURSOR_ERROR,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
|
||||
case 429:
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
|
||||
case 403:
|
||||
@@ -75,14 +63,12 @@ export const parseGmailMessagesImportError = (
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
}
|
||||
if (reason === 'domainPolicy') {
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -92,14 +78,12 @@ export const parseGmailMessagesImportError = (
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
|
||||
case 503:
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
|
||||
case 500:
|
||||
@@ -109,7 +93,6 @@ export const parseGmailMessagesImportError = (
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -117,7 +100,6 @@ export const parseGmailMessagesImportError = (
|
||||
return new MessageImportDriverException(
|
||||
`${code} - ${reason} - ${message}`,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
}
|
||||
break;
|
||||
@@ -129,6 +111,5 @@ export const parseGmailMessagesImportError = (
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.UNKNOWN,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
};
|
||||
+22
-44
@@ -2,119 +2,98 @@ import {
|
||||
MessageImportDriverException,
|
||||
MessageImportDriverExceptionCode,
|
||||
} from 'src/modules/messaging/message-import-manager/drivers/exceptions/message-import-driver.exception';
|
||||
import { type GmailApiError } from 'src/modules/messaging/message-import-manager/drivers/gmail/types/gmail-api-error.type';
|
||||
|
||||
export const parseGmailMessageListFetchError = (
|
||||
error: {
|
||||
code?: number;
|
||||
errors: {
|
||||
reason: string;
|
||||
message: string;
|
||||
}[];
|
||||
},
|
||||
options?: { cause?: Error },
|
||||
export const parseGmailApiError = (
|
||||
error: GmailApiError,
|
||||
): MessageImportDriverException => {
|
||||
const { code, errors } = error;
|
||||
|
||||
const reason = errors?.[0]?.reason;
|
||||
const message = errors?.[0]?.message;
|
||||
const { code, message } = error;
|
||||
|
||||
switch (code) {
|
||||
case 400:
|
||||
if (reason === 'invalid_grant') {
|
||||
case '400':
|
||||
if (message === 'invalid_grant') {
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
}
|
||||
if (reason === 'failedPrecondition') {
|
||||
if (message === 'failedPrecondition') {
|
||||
if (message.includes('Mail service not enabled')) {
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
}
|
||||
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
}
|
||||
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.UNKNOWN,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
|
||||
case 404:
|
||||
case '404':
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.SYNC_CURSOR_ERROR,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
|
||||
case 429:
|
||||
case '429':
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
|
||||
case 403:
|
||||
case '403':
|
||||
if (
|
||||
reason === 'rateLimitExceeded' ||
|
||||
reason === 'userRateLimitExceeded' ||
|
||||
reason === 'dailyLimitExceeded'
|
||||
message === 'rateLimitExceeded' ||
|
||||
message === 'userRateLimitExceeded' ||
|
||||
message === 'dailyLimitExceeded'
|
||||
) {
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
}
|
||||
if (reason === 'domainPolicy') {
|
||||
if (message === 'domainPolicy') {
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 401:
|
||||
case '401':
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
|
||||
case 503:
|
||||
case '503':
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
|
||||
case 500:
|
||||
case 502:
|
||||
case 504:
|
||||
if (reason === 'backendError') {
|
||||
case '500':
|
||||
case '502':
|
||||
case '504':
|
||||
if (message === 'backendError') {
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
}
|
||||
|
||||
if (errors?.[0]?.message.includes(`Authentication backend unavailable`)) {
|
||||
if (message.includes(`Authentication backend unavailable`)) {
|
||||
return new MessageImportDriverException(
|
||||
`${code} - ${reason} - ${message}`,
|
||||
`${code} - ${message}`,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
}
|
||||
break;
|
||||
@@ -126,6 +105,5 @@ export const parseGmailMessageListFetchError = (
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
MessageImportDriverExceptionCode.UNKNOWN,
|
||||
{ cause: options?.cause },
|
||||
);
|
||||
};
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import { type GaxiosError } from 'gaxios';
|
||||
|
||||
import {
|
||||
MessageImportDriverException,
|
||||
MessageImportDriverExceptionCode,
|
||||
} from 'src/modules/messaging/message-import-manager/drivers/exceptions/message-import-driver.exception';
|
||||
|
||||
export const parseGmailNetworkError = (
|
||||
error: GaxiosError,
|
||||
): MessageImportDriverException | null => {
|
||||
return new MessageImportDriverException(
|
||||
error.message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
{ cause: error },
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user