diff --git a/packages/datastore/src/sync/processors/errorMaps.ts b/packages/datastore/src/sync/processors/errorMaps.ts new file mode 100644 index 00000000000..2747cf66555 --- /dev/null +++ b/packages/datastore/src/sync/processors/errorMaps.ts @@ -0,0 +1,63 @@ +import { ErrorType } from '../../types'; + +export type ErrorMap = Partial<{ + [key in ErrorType]: (error: Error) => boolean; +}>; + +export const mutationErrorMap: ErrorMap = { + BadRecord: error => /^Cannot return \w+ for [\w-_]+ type/.test(error.message), + ConfigError: () => false, + Transient: () => false, + Unauthorized: () => false, +}; + +export const subscriptionErrorMap: ErrorMap = { + BadRecord: () => false, + ConfigError: () => false, + Transient: () => false, + Unauthorized: (givenError: any) => { + const { + error: { errors: [{ message = '' } = {}] } = { + errors: [], + }, + } = givenError; + const regex = /Connection failed.+Unauthorized/; + return regex.test(message); + }, +}; + +export const syncErrorMap: ErrorMap = { + BadRecord: error => /^Cannot return \w+ for [\w-_]+ type/.test(error.message), + ConfigError: () => false, + Transient: () => false, + Unauthorized: () => false, +}; + +export function getMutationErrorType(error: Error): ErrorType { + return mapErrorToType(mutationErrorMap, error); +} + +export function getSubscriptionErrorType(error: Error): ErrorType { + return mapErrorToType(subscriptionErrorMap, error); +} + +export function getSyncErrorType(error: Error): ErrorType { + return mapErrorToType(syncErrorMap, error); +} + +/** + * Categorizes an error with a broad error type, intended to make + * customer error handling code simpler. + * @param errorMap Error names and a list of patterns that indicate them (each pattern as a regex or function) + * @param error The underying error to categorize. + */ +export function mapErrorToType(errorMap: ErrorMap, error: Error): ErrorType { + const errorTypes = [...Object.keys(errorMap)] as ErrorType[]; + for (const errorType of errorTypes) { + const matcher = errorMap[errorType]; + if (matcher(error)) { + return errorType; + } + } + return 'Unknown'; +} diff --git a/packages/datastore/src/sync/processors/mutation.ts b/packages/datastore/src/sync/processors/mutation.ts index a21a3f1a1b6..681603372fe 100644 --- a/packages/datastore/src/sync/processors/mutation.ts +++ b/packages/datastore/src/sync/processors/mutation.ts @@ -34,19 +34,13 @@ import { getModelAuthModes, TransformerMutationType, getTokenForCustomAuth, - ErrorMap, - mapErrorToType, } from '../utils'; +import { getMutationErrorType } from './errorMaps'; const MAX_ATTEMPTS = 10; const logger = new Logger('DataStore'); -// TODO: add additional error maps -const errorMap = { - BadRecord: error => /^Cannot return \w+ for [\w-_]+ type/.test(error.message), -} as ErrorMap; - type MutationProcessorEvent = { operation: TransformerMutationType; modelDefinition: SchemaModel; @@ -386,7 +380,7 @@ class MutationProcessor { localModel: variables.input, message: error.message, operation, - errorType: mapErrorToType(errorMap, error), + errorType: getMutationErrorType(error), errorInfo: error.errorInfo, process: ProcessName.mutate, cause: error, diff --git a/packages/datastore/src/sync/processors/subscription.ts b/packages/datastore/src/sync/processors/subscription.ts index cff0cf853fd..a548a6ddd8a 100644 --- a/packages/datastore/src/sync/processors/subscription.ts +++ b/packages/datastore/src/sync/processors/subscription.ts @@ -22,27 +22,13 @@ import { getUserGroupsFromToken, TransformerMutationType, getTokenForCustomAuth, - mapErrorToType, - ErrorMap, } from '../utils'; import { ModelPredicateCreator } from '../../predicates'; import { validatePredicate } from '../../util'; +import { getSubscriptionErrorType } from './errorMaps'; const logger = new Logger('DataStore'); -// TODO: add additional error maps -const errorMap = { - Unauthorized: (givenError: any) => { - const { - error: { errors: [{ message = '' } = {}] } = { - errors: [], - }, - } = givenError; - const regex = /Connection failed.+Unauthorized/; - return regex.test(message); - }, -} as ErrorMap; - export enum CONTROL_MSG { CONNECTED = 'CONNECTED', } @@ -468,10 +454,8 @@ class SubscriptionProcessor { message, model: modelDefinition.name, operation, - errorType: mapErrorToType( - errorMap, - subscriptionError - ), + errorType: + getSubscriptionErrorType(subscriptionError), process: ProcessName.subscribe, remoteModel: null, cause: subscriptionError, diff --git a/packages/datastore/src/sync/processors/sync.ts b/packages/datastore/src/sync/processors/sync.ts index 428eacc0731..bc8e615536a 100644 --- a/packages/datastore/src/sync/processors/sync.ts +++ b/packages/datastore/src/sync/processors/sync.ts @@ -18,8 +18,6 @@ import { getForbiddenError, predicateToGraphQLFilter, getTokenForCustomAuth, - mapErrorToType, - ErrorMap, } from '../utils'; import { jitteredExponentialRetry, @@ -29,6 +27,7 @@ import { } from '@aws-amplify/core'; import { ModelPredicateCreator } from '../../predicates'; import { ModelInstanceCreator } from '../../datastore/datastore'; +import { getSyncErrorType } from './errorMaps'; const opResultDefaults = { items: [], nextToken: null, @@ -37,11 +36,6 @@ const opResultDefaults = { const logger = new Logger('DataStore'); -// TODO: add additional error maps -const errorMap = { - BadRecord: error => /^Cannot return \w+ for [\w-_]+ type/.test(error.message), -} as ErrorMap; - class SyncProcessor { private readonly typeQuery = new WeakMap(); @@ -251,7 +245,7 @@ class SyncProcessor { message: err.message, model: modelDefinition.name, operation: opName, - errorType: mapErrorToType(errorMap, err), + errorType: getSyncErrorType(err), process: ProcessName.sync, remoteModel: null, cause: err, diff --git a/packages/datastore/src/sync/utils.ts b/packages/datastore/src/sync/utils.ts index 35d5126b7b2..04d9dea6cf5 100644 --- a/packages/datastore/src/sync/utils.ts +++ b/packages/datastore/src/sync/utils.ts @@ -26,7 +26,6 @@ import { ModelOperation, InternalSchema, AuthModeStrategy, - ErrorType, } from '../types'; import { exhaustiveCheck } from '../util'; import { MutationEvent } from './'; @@ -41,27 +40,6 @@ enum GraphQLOperationType { GET = 'query', } -export type ErrorMap = { - [key in ErrorType]: (error: Error) => boolean; -}; - -/** - * Categorizes an error with a broad error type, intended to make - * customer error handling code simpler. - * @param errorMap Error names and a list of patterns that indicate them (each pattern as a regex or function) - * @param error The underying error to categorize. - */ -export function mapErrorToType(errorMap: ErrorMap, error: Error): ErrorType { - const errorTypes = [...Object.keys(errorMap)] as ErrorType[]; - for (const errorType of errorTypes) { - const matcher = errorMap[errorType]; - if (matcher(error)) { - return errorType; - } - } - return 'Unknown'; -} - export enum TransformerMutationType { CREATE = 'Create', UPDATE = 'Update',