fix messaging error parsing (#16448)
This commit is contained in:
+3
-2
@@ -1,10 +1,11 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { GaxiosError } from 'gaxios';
|
||||
|
||||
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';
|
||||
@@ -21,7 +22,7 @@ export class GmailEmailAliasErrorHandlerService {
|
||||
throw parseGmailNetworkError(error);
|
||||
}
|
||||
|
||||
if (isGmailApiError(error)) {
|
||||
if (error instanceof GaxiosError) {
|
||||
throw parseGmailApiError(error);
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -1,10 +1,11 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { GaxiosError } from 'gaxios';
|
||||
|
||||
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';
|
||||
@@ -23,7 +24,7 @@ export class GmailFoldersErrorHandlerService {
|
||||
throw parseGmailNetworkError(error);
|
||||
}
|
||||
|
||||
if (isGmailApiError(error)) {
|
||||
if (error instanceof GaxiosError) {
|
||||
throw parseGmailApiError(error);
|
||||
}
|
||||
|
||||
|
||||
+77
-162
@@ -1,173 +1,88 @@
|
||||
import { type GmailApiError } from 'src/modules/messaging/message-import-manager/drivers/gmail/types/gmail-api-error.type';
|
||||
import { GaxiosError } from 'gaxios';
|
||||
|
||||
const gmailApiErrorMocks = {
|
||||
// 400 Bad Request - Invalid query parameters
|
||||
badRequest: {
|
||||
code: 400,
|
||||
message: 'badRequest',
|
||||
},
|
||||
|
||||
// 400 Invalid Grant
|
||||
invalidGrant: {
|
||||
code: 400,
|
||||
message: 'invalid_grant',
|
||||
},
|
||||
|
||||
// 400 Failed Precondition
|
||||
failedPrecondition: {
|
||||
code: 400,
|
||||
message: 'failedPrecondition',
|
||||
},
|
||||
|
||||
invalidCredentials: {
|
||||
code: 401,
|
||||
message: 'authError',
|
||||
},
|
||||
|
||||
notFound: {
|
||||
code: 404,
|
||||
message: 'notFound',
|
||||
},
|
||||
|
||||
gone: {
|
||||
code: 410,
|
||||
message: 'resourceGone',
|
||||
},
|
||||
|
||||
dailyLimitExceeded: {
|
||||
code: 403,
|
||||
message: 'dailyLimitExceeded',
|
||||
},
|
||||
|
||||
userRateLimitExceeded: {
|
||||
code: 403,
|
||||
message: 'userRateLimitExceeded',
|
||||
},
|
||||
|
||||
rateLimitExceeded: {
|
||||
code: 403,
|
||||
message: 'rateLimitExceeded',
|
||||
},
|
||||
|
||||
domainPolicyError: {
|
||||
code: 403,
|
||||
message: 'domainPolicy',
|
||||
},
|
||||
|
||||
tooManyConcurrentRequests: {
|
||||
code: 429,
|
||||
message: 'tooManyConcurrentRequests',
|
||||
},
|
||||
|
||||
backendError: {
|
||||
code: 500,
|
||||
message: 'backendError',
|
||||
},
|
||||
type ErrorConfig = {
|
||||
reason: string;
|
||||
message: string;
|
||||
};
|
||||
|
||||
const convertToErrorWithErrorCodeStringOrNumber = ({
|
||||
error,
|
||||
errorCodeAsString,
|
||||
}: {
|
||||
error: GmailApiError;
|
||||
errorCodeAsString: boolean;
|
||||
}): GmailApiError => {
|
||||
return {
|
||||
code: errorCodeAsString ? error.code.toString() : error.code,
|
||||
message: error.message,
|
||||
};
|
||||
const ERROR_DEFINITIONS: Record<number, Record<string, ErrorConfig>> = {
|
||||
400: {
|
||||
default: { reason: 'badRequest', message: 'Bad Request' },
|
||||
invalid_grant: { reason: 'invalid_grant', message: 'invalid_grant' },
|
||||
failedPrecondition: {
|
||||
reason: 'failedPrecondition',
|
||||
message: 'Precondition check failed.',
|
||||
},
|
||||
},
|
||||
401: {
|
||||
default: { reason: 'authError', message: 'Invalid Credentials' },
|
||||
},
|
||||
403: {
|
||||
default: { reason: 'rateLimitExceeded', message: 'Rate Limit Exceeded' },
|
||||
dailyLimit: {
|
||||
reason: 'dailyLimitExceeded',
|
||||
message: 'Daily Limit Exceeded',
|
||||
},
|
||||
userRateLimit: {
|
||||
reason: 'userRateLimitExceeded',
|
||||
message: 'User Rate Limit Exceeded',
|
||||
},
|
||||
rateLimit: { reason: 'rateLimitExceeded', message: 'Rate Limit Exceeded' },
|
||||
domainPolicy: { reason: 'domainPolicy', message: 'Domain Policy Error' },
|
||||
},
|
||||
404: {
|
||||
default: { reason: 'notFound', message: 'Not Found' },
|
||||
},
|
||||
410: {
|
||||
default: { reason: 'resourceGone', message: 'Resource Gone' },
|
||||
},
|
||||
429: {
|
||||
default: {
|
||||
reason: 'tooManyConcurrentRequests',
|
||||
message: 'Too Many Concurrent Requests',
|
||||
},
|
||||
},
|
||||
500: {
|
||||
default: { reason: 'backendError', message: 'Backend Error' },
|
||||
},
|
||||
};
|
||||
|
||||
export const getGmailApiError = ({
|
||||
code,
|
||||
type,
|
||||
errorCodeAsString = false,
|
||||
reason,
|
||||
}: {
|
||||
code: number;
|
||||
type?: string;
|
||||
errorCodeAsString?: boolean;
|
||||
}): GmailApiError => {
|
||||
switch (code) {
|
||||
case 400:
|
||||
switch (type) {
|
||||
case 'invalid_grant':
|
||||
return convertToErrorWithErrorCodeStringOrNumber({
|
||||
error: gmailApiErrorMocks.invalidGrant,
|
||||
errorCodeAsString,
|
||||
});
|
||||
case 'failedPrecondition':
|
||||
return convertToErrorWithErrorCodeStringOrNumber({
|
||||
error: gmailApiErrorMocks.failedPrecondition,
|
||||
errorCodeAsString,
|
||||
});
|
||||
default:
|
||||
return convertToErrorWithErrorCodeStringOrNumber({
|
||||
error: gmailApiErrorMocks.badRequest,
|
||||
errorCodeAsString,
|
||||
});
|
||||
}
|
||||
case 401:
|
||||
return convertToErrorWithErrorCodeStringOrNumber({
|
||||
error: gmailApiErrorMocks.invalidCredentials,
|
||||
errorCodeAsString,
|
||||
});
|
||||
case 403:
|
||||
switch (type) {
|
||||
case 'dailyLimit':
|
||||
return convertToErrorWithErrorCodeStringOrNumber({
|
||||
error: gmailApiErrorMocks.dailyLimitExceeded,
|
||||
errorCodeAsString,
|
||||
});
|
||||
case 'userRateLimit':
|
||||
return convertToErrorWithErrorCodeStringOrNumber({
|
||||
error: gmailApiErrorMocks.userRateLimitExceeded,
|
||||
errorCodeAsString,
|
||||
});
|
||||
case 'rateLimit':
|
||||
return convertToErrorWithErrorCodeStringOrNumber({
|
||||
error: gmailApiErrorMocks.rateLimitExceeded,
|
||||
errorCodeAsString,
|
||||
});
|
||||
case 'domainPolicy':
|
||||
return convertToErrorWithErrorCodeStringOrNumber({
|
||||
error: gmailApiErrorMocks.domainPolicyError,
|
||||
errorCodeAsString,
|
||||
});
|
||||
default:
|
||||
return convertToErrorWithErrorCodeStringOrNumber({
|
||||
error: gmailApiErrorMocks.rateLimitExceeded,
|
||||
errorCodeAsString,
|
||||
});
|
||||
}
|
||||
case 404:
|
||||
return convertToErrorWithErrorCodeStringOrNumber({
|
||||
error: gmailApiErrorMocks.notFound,
|
||||
errorCodeAsString,
|
||||
});
|
||||
case 410:
|
||||
return convertToErrorWithErrorCodeStringOrNumber({
|
||||
error: gmailApiErrorMocks.gone,
|
||||
errorCodeAsString,
|
||||
});
|
||||
case 429:
|
||||
switch (type) {
|
||||
case 'concurrent':
|
||||
return convertToErrorWithErrorCodeStringOrNumber({
|
||||
error: gmailApiErrorMocks.tooManyConcurrentRequests,
|
||||
errorCodeAsString,
|
||||
});
|
||||
default:
|
||||
return convertToErrorWithErrorCodeStringOrNumber({
|
||||
error: gmailApiErrorMocks.tooManyConcurrentRequests,
|
||||
errorCodeAsString,
|
||||
});
|
||||
}
|
||||
case 500:
|
||||
return convertToErrorWithErrorCodeStringOrNumber({
|
||||
error: gmailApiErrorMocks.backendError,
|
||||
errorCodeAsString,
|
||||
});
|
||||
default:
|
||||
throw new Error(`Unknown error code: ${code}`);
|
||||
reason?: string;
|
||||
}): GaxiosError => {
|
||||
const statusMap = ERROR_DEFINITIONS[code];
|
||||
|
||||
if (!statusMap) {
|
||||
throw new Error(`Unknown error code: ${code}`);
|
||||
}
|
||||
|
||||
const config = statusMap[reason || ''] ?? statusMap.default;
|
||||
|
||||
return new GaxiosError(
|
||||
config.message,
|
||||
{ url: 'https://gmail.googleapis.com/mocks' },
|
||||
{
|
||||
status: code,
|
||||
statusText: config.message,
|
||||
data: {
|
||||
error: {
|
||||
code,
|
||||
message: config.message,
|
||||
errors: [
|
||||
{
|
||||
message: config.message,
|
||||
reason: config.reason,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
headers: {},
|
||||
config: { url: 'https://gmail.googleapis.com/mocks' },
|
||||
request: { responseURL: 'https://gmail.googleapis.com/mocks' },
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
+3
-2
@@ -1,10 +1,11 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { GaxiosError } from 'gaxios';
|
||||
|
||||
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';
|
||||
@@ -23,7 +24,7 @@ export class GmailMessageListFetchErrorHandler {
|
||||
throw parseGmailNetworkError(error);
|
||||
}
|
||||
|
||||
if (isGmailApiError(error)) {
|
||||
if (error instanceof GaxiosError) {
|
||||
throw parseGmailApiError(error);
|
||||
}
|
||||
|
||||
|
||||
+21
-135
@@ -7,10 +7,7 @@ import { parseGmailApiError } from 'src/modules/messaging/message-import-manager
|
||||
|
||||
describe('parseGmailApiError', () => {
|
||||
it('should handle 400 Bad Request', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 400,
|
||||
errorCodeAsString: false,
|
||||
});
|
||||
const error = getGmailApiError({ code: 400 });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -18,11 +15,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 400 Invalid Grant', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 400,
|
||||
type: 'invalid_grant',
|
||||
errorCodeAsString: false,
|
||||
});
|
||||
const error = getGmailApiError({ code: 400, reason: 'invalid_grant' });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -32,11 +25,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 400 Failed Precondition', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 400,
|
||||
type: 'failedPrecondition',
|
||||
errorCodeAsString: false,
|
||||
});
|
||||
const error = getGmailApiError({ code: 400, reason: 'failedPrecondition' });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -46,10 +35,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 401 Invalid Credentials', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 401,
|
||||
errorCodeAsString: false,
|
||||
});
|
||||
const error = getGmailApiError({ code: 401 });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -59,11 +45,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 403 Daily Limit Exceeded', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 403,
|
||||
type: 'dailyLimit',
|
||||
errorCodeAsString: false,
|
||||
});
|
||||
const error = getGmailApiError({ code: 403, reason: 'dailyLimit' });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -73,11 +55,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 403 User Rate Limit Exceeded', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 403,
|
||||
type: 'userRateLimit',
|
||||
errorCodeAsString: false,
|
||||
});
|
||||
const error = getGmailApiError({ code: 403, reason: 'userRateLimit' });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -87,11 +65,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 403 Rate Limit Exceeded', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 403,
|
||||
type: 'rateLimit',
|
||||
errorCodeAsString: false,
|
||||
});
|
||||
const error = getGmailApiError({ code: 403, reason: 'rateLimit' });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -101,11 +75,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 403 Domain Policy Error', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 403,
|
||||
type: 'domainPolicy',
|
||||
errorCodeAsString: false,
|
||||
});
|
||||
const error = getGmailApiError({ code: 403, reason: 'domainPolicy' });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -115,10 +85,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 404 as sync cursor error', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 404,
|
||||
errorCodeAsString: false,
|
||||
});
|
||||
const error = getGmailApiError({ code: 404 });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -128,10 +95,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 410 Gone', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 410,
|
||||
errorCodeAsString: false,
|
||||
});
|
||||
const error = getGmailApiError({ code: 410 });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -139,11 +103,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 429 Too Many Requests', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 429,
|
||||
type: 'concurrent',
|
||||
errorCodeAsString: false,
|
||||
});
|
||||
const error = getGmailApiError({ code: 429, reason: 'rateLimit' });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -153,10 +113,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 500 Backend Error', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 500,
|
||||
errorCodeAsString: false,
|
||||
});
|
||||
const error = getGmailApiError({ code: 500, reason: 'backendError' });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -166,10 +123,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 400 Bad Request with errorCodeAsString', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 400,
|
||||
errorCodeAsString: true,
|
||||
});
|
||||
const error = getGmailApiError({ code: 400, reason: 'badRequest' });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -177,11 +131,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 400 Invalid Grant with errorCodeAsString', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 400,
|
||||
type: 'invalid_grant',
|
||||
errorCodeAsString: true,
|
||||
});
|
||||
const error = getGmailApiError({ code: 400, reason: 'invalid_grant' });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -191,11 +141,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 400 Failed Precondition with errorCodeAsString', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 400,
|
||||
type: 'failedPrecondition',
|
||||
errorCodeAsString: true,
|
||||
});
|
||||
const error = getGmailApiError({ code: 400, reason: 'failedPrecondition' });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -205,10 +151,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 401 Invalid Credentials with errorCodeAsString', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 401,
|
||||
errorCodeAsString: true,
|
||||
});
|
||||
const error = getGmailApiError({ code: 401 });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -218,11 +161,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 403 Daily Limit Exceeded with errorCodeAsString', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 403,
|
||||
type: 'dailyLimit',
|
||||
errorCodeAsString: true,
|
||||
});
|
||||
const error = getGmailApiError({ code: 403, reason: 'dailyLimit' });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -232,11 +171,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 403 User Rate Limit Exceeded with errorCodeAsString', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 403,
|
||||
type: 'userRateLimit',
|
||||
errorCodeAsString: true,
|
||||
});
|
||||
const error = getGmailApiError({ code: 403, reason: 'userRateLimit' });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -246,11 +181,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 403 Rate Limit Exceeded with errorCodeAsString', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 403,
|
||||
type: 'rateLimit',
|
||||
errorCodeAsString: true,
|
||||
});
|
||||
const error = getGmailApiError({ code: 403, reason: 'rateLimit' });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -260,11 +191,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 403 Domain Policy Error with errorCodeAsString', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 403,
|
||||
type: 'domainPolicy',
|
||||
errorCodeAsString: true,
|
||||
});
|
||||
const error = getGmailApiError({ code: 403, reason: 'domainPolicy' });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -274,10 +201,7 @@ describe('parseGmailApiError', () => {
|
||||
});
|
||||
|
||||
it('should handle 404 as sync cursor error with errorCodeAsString', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 404,
|
||||
errorCodeAsString: true,
|
||||
});
|
||||
const error = getGmailApiError({ code: 404 });
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
@@ -285,42 +209,4 @@ describe('parseGmailApiError', () => {
|
||||
MessageImportDriverExceptionCode.SYNC_CURSOR_ERROR,
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle 410 Gone with errorCodeAsString', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 410,
|
||||
errorCodeAsString: true,
|
||||
});
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception.code).toBe(MessageImportDriverExceptionCode.UNKNOWN);
|
||||
});
|
||||
|
||||
it('should handle 429 Too Many Requests with errorCodeAsString', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 429,
|
||||
type: 'concurrent',
|
||||
errorCodeAsString: true,
|
||||
});
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception.code).toBe(
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle 500 Backend Error with errorCodeAsString', () => {
|
||||
const error = getGmailApiError({
|
||||
code: 500,
|
||||
errorCodeAsString: true,
|
||||
});
|
||||
const exception = parseGmailApiError(error);
|
||||
|
||||
expect(exception).toBeInstanceOf(MessageImportDriverException);
|
||||
expect(exception.code).toBe(
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
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 !== 'number' && typeof error.code !== 'string') ||
|
||||
!('message' in error) ||
|
||||
typeof error.message !== 'string'
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
+46
-28
@@ -1,69 +1,85 @@
|
||||
import { type GaxiosError } from 'gaxios';
|
||||
|
||||
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 parseGmailApiError = (
|
||||
error: GmailApiError,
|
||||
error: GaxiosError,
|
||||
): MessageImportDriverException => {
|
||||
const { code, message } = error;
|
||||
const gmailApiError = {
|
||||
code: error.response?.status,
|
||||
reason:
|
||||
error.response?.data?.error?.errors?.[0].reason ||
|
||||
error.response?.data?.error ||
|
||||
'Unknown reason',
|
||||
message:
|
||||
error.response?.data?.error?.errors?.[0].message ||
|
||||
error.response?.data?.error_description ||
|
||||
'Unknown error',
|
||||
};
|
||||
|
||||
const codeAsNumber = Number(code);
|
||||
|
||||
switch (codeAsNumber) {
|
||||
switch (gmailApiError.code) {
|
||||
case 400:
|
||||
if (message === 'invalid_grant') {
|
||||
if (gmailApiError.reason === 'invalid_grant') {
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
gmailApiError.message,
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
);
|
||||
}
|
||||
if (message === 'failedPrecondition') {
|
||||
if (message.includes('Mail service not enabled')) {
|
||||
if (gmailApiError.reason === 'failedPrecondition') {
|
||||
if (gmailApiError.message.includes('Mail service not enabled')) {
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
gmailApiError.message,
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
);
|
||||
}
|
||||
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
gmailApiError.message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
);
|
||||
}
|
||||
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
gmailApiError.message,
|
||||
MessageImportDriverExceptionCode.UNKNOWN,
|
||||
);
|
||||
|
||||
case 404:
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
gmailApiError.message,
|
||||
MessageImportDriverExceptionCode.SYNC_CURSOR_ERROR,
|
||||
);
|
||||
|
||||
case 429:
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
gmailApiError.message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
);
|
||||
|
||||
case 403:
|
||||
if (
|
||||
message === 'rateLimitExceeded' ||
|
||||
message === 'userRateLimitExceeded' ||
|
||||
message === 'dailyLimitExceeded'
|
||||
gmailApiError.reason === 'rateLimitExceeded' ||
|
||||
gmailApiError.reason === 'userRateLimitExceeded' ||
|
||||
gmailApiError.reason === 'dailyLimitExceeded'
|
||||
) {
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
gmailApiError.message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
);
|
||||
}
|
||||
if (message === 'domainPolicy') {
|
||||
if (gmailApiError.reason === 'domainPolicy') {
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
gmailApiError.message,
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
);
|
||||
}
|
||||
|
||||
if (gmailApiError.reason === 'insufficientPermissions') {
|
||||
return new MessageImportDriverException(
|
||||
gmailApiError.message,
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
);
|
||||
}
|
||||
@@ -72,29 +88,31 @@ export const parseGmailApiError = (
|
||||
|
||||
case 401:
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
gmailApiError.message,
|
||||
MessageImportDriverExceptionCode.INSUFFICIENT_PERMISSIONS,
|
||||
);
|
||||
|
||||
case 503:
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
gmailApiError.message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
);
|
||||
|
||||
case 500:
|
||||
case 502:
|
||||
case 504:
|
||||
if (message === 'backendError') {
|
||||
if (gmailApiError.reason === 'backendError') {
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
gmailApiError.message,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
);
|
||||
}
|
||||
|
||||
if (message.includes(`Authentication backend unavailable`)) {
|
||||
if (
|
||||
gmailApiError.message.includes(`Authentication backend unavailable`)
|
||||
) {
|
||||
return new MessageImportDriverException(
|
||||
`${code} - ${message}`,
|
||||
`${gmailApiError.code} - ${gmailApiError.message}`,
|
||||
MessageImportDriverExceptionCode.TEMPORARY_ERROR,
|
||||
);
|
||||
}
|
||||
@@ -105,7 +123,7 @@ export const parseGmailApiError = (
|
||||
}
|
||||
|
||||
return new MessageImportDriverException(
|
||||
message,
|
||||
gmailApiError.message,
|
||||
MessageImportDriverExceptionCode.UNKNOWN,
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user