mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-24 12:34:10 +03:00
Handle query runner errors (#6424)
- Throw service error from query runner - Catch in resolver factories - Map to graphql errors --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
parent
3ff24658e1
commit
3060eb4e1e
@ -6,25 +6,25 @@ import {
|
|||||||
YogaDriverConfig,
|
YogaDriverConfig,
|
||||||
YogaDriverServerContext,
|
YogaDriverServerContext,
|
||||||
} from '@graphql-yoga/nestjs';
|
} from '@graphql-yoga/nestjs';
|
||||||
import { GraphQLSchema, GraphQLError } from 'graphql';
|
|
||||||
import GraphQLJSON from 'graphql-type-json';
|
|
||||||
import { JsonWebTokenError, TokenExpiredError } from 'jsonwebtoken';
|
|
||||||
import { GraphQLSchemaWithContext, YogaInitialContext } from 'graphql-yoga';
|
|
||||||
import * as Sentry from '@sentry/node';
|
import * as Sentry from '@sentry/node';
|
||||||
|
import { GraphQLError, GraphQLSchema } from 'graphql';
|
||||||
|
import GraphQLJSON from 'graphql-type-json';
|
||||||
|
import { GraphQLSchemaWithContext, YogaInitialContext } from 'graphql-yoga';
|
||||||
|
import { JsonWebTokenError, TokenExpiredError } from 'jsonwebtoken';
|
||||||
|
|
||||||
import { TokenService } from 'src/engine/core-modules/auth/services/token.service';
|
import { useThrottler } from 'src/engine/api/graphql/graphql-config/hooks/use-throttler';
|
||||||
import { CoreEngineModule } from 'src/engine/core-modules/core-engine.module';
|
|
||||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
|
||||||
import { WorkspaceSchemaFactory } from 'src/engine/api/graphql/workspace-schema.factory';
|
import { WorkspaceSchemaFactory } from 'src/engine/api/graphql/workspace-schema.factory';
|
||||||
|
import { TokenService } from 'src/engine/core-modules/auth/services/token.service';
|
||||||
|
import { JwtData } from 'src/engine/core-modules/auth/types/jwt-data.type';
|
||||||
|
import { CoreEngineModule } from 'src/engine/core-modules/core-engine.module';
|
||||||
|
import { useGraphQLErrorHandlerHook } from 'src/engine/core-modules/graphql/hooks/use-graphql-error-handler.hook';
|
||||||
|
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||||
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
|
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||||
import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service';
|
import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service';
|
||||||
|
import { useSentryTracing } from 'src/engine/integrations/exception-handler/hooks/use-sentry-tracing';
|
||||||
import { handleExceptionAndConvertToGraphQLError } from 'src/engine/utils/global-exception-handler.util';
|
import { handleExceptionAndConvertToGraphQLError } from 'src/engine/utils/global-exception-handler.util';
|
||||||
import { renderApolloPlayground } from 'src/engine/utils/render-apollo-playground.util';
|
import { renderApolloPlayground } from 'src/engine/utils/render-apollo-playground.util';
|
||||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
|
||||||
import { useExceptionHandler } from 'src/engine/integrations/exception-handler/hooks/use-exception-handler.hook';
|
|
||||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
|
||||||
import { useThrottler } from 'src/engine/api/graphql/graphql-config/hooks/use-throttler';
|
|
||||||
import { JwtData } from 'src/engine/core-modules/auth/types/jwt-data.type';
|
|
||||||
import { useSentryTracing } from 'src/engine/integrations/exception-handler/hooks/use-sentry-tracing';
|
|
||||||
|
|
||||||
export interface GraphQLContext extends YogaDriverServerContext<'express'> {
|
export interface GraphQLContext extends YogaDriverServerContext<'express'> {
|
||||||
user?: User;
|
user?: User;
|
||||||
@ -52,7 +52,7 @@ export class GraphQLConfigService
|
|||||||
return context.req.user?.id ?? context.req.ip ?? 'anonymous';
|
return context.req.user?.id ?? context.req.ip ?? 'anonymous';
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
useExceptionHandler({
|
useGraphQLErrorHandlerHook({
|
||||||
exceptionHandlerService: this.exceptionHandlerService,
|
exceptionHandlerService: this.exceptionHandlerService,
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
import { BadRequestException } from '@nestjs/common';
|
import {
|
||||||
|
WorkspaceQueryRunnerException,
|
||||||
|
WorkspaceQueryRunnerExceptionCode,
|
||||||
|
} from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.exception';
|
||||||
|
|
||||||
export const assertIsValidUuid = (value: string) => {
|
export const assertIsValidUuid = (value: string) => {
|
||||||
const isValid =
|
const isValid =
|
||||||
@ -7,6 +10,9 @@ export const assertIsValidUuid = (value: string) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
throw new BadRequestException(`Value "${value}" is not a valid UUID`);
|
throw new WorkspaceQueryRunnerException(
|
||||||
|
`Value "${value}" is not a valid UUID`,
|
||||||
|
WorkspaceQueryRunnerExceptionCode.INVALID_QUERY_INPUT,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
BadRequestException,
|
WorkspaceQueryRunnerException,
|
||||||
HttpException,
|
WorkspaceQueryRunnerExceptionCode,
|
||||||
InternalServerErrorException,
|
} from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.exception';
|
||||||
} from '@nestjs/common';
|
|
||||||
|
|
||||||
export type PgGraphQLConfig = {
|
export type PgGraphQLConfig = {
|
||||||
atMost: number;
|
atMost: number;
|
||||||
@ -13,7 +12,7 @@ interface PgGraphQLErrorMapping {
|
|||||||
command: string,
|
command: string,
|
||||||
objectName: string,
|
objectName: string,
|
||||||
pgGraphqlConfig: PgGraphQLConfig,
|
pgGraphqlConfig: PgGraphQLConfig,
|
||||||
) => HttpException;
|
) => WorkspaceQueryRunnerException;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pgGraphQLCommandMapping = {
|
const pgGraphQLCommandMapping = {
|
||||||
@ -24,18 +23,28 @@ const pgGraphQLCommandMapping = {
|
|||||||
|
|
||||||
const pgGraphQLErrorMapping: PgGraphQLErrorMapping = {
|
const pgGraphQLErrorMapping: PgGraphQLErrorMapping = {
|
||||||
'delete impacts too many records': (_, objectName, pgGraphqlConfig) =>
|
'delete impacts too many records': (_, objectName, pgGraphqlConfig) =>
|
||||||
new BadRequestException(
|
new WorkspaceQueryRunnerException(
|
||||||
`Cannot delete ${objectName} because it impacts too many records (more than ${pgGraphqlConfig?.atMost}).`,
|
`Cannot delete ${objectName} because it impacts too many records (more than ${pgGraphqlConfig?.atMost}).`,
|
||||||
|
WorkspaceQueryRunnerExceptionCode.TOO_MANY_ROWS_AFFECTED,
|
||||||
),
|
),
|
||||||
'update impacts too many records': (_, objectName, pgGraphqlConfig) =>
|
'update impacts too many records': (_, objectName, pgGraphqlConfig) =>
|
||||||
new BadRequestException(
|
new WorkspaceQueryRunnerException(
|
||||||
`Cannot update ${objectName} because it impacts too many records (more than ${pgGraphqlConfig?.atMost}).`,
|
`Cannot update ${objectName} because it impacts too many records (more than ${pgGraphqlConfig?.atMost}).`,
|
||||||
|
WorkspaceQueryRunnerExceptionCode.TOO_MANY_ROWS_AFFECTED,
|
||||||
),
|
),
|
||||||
'duplicate key value violates unique constraint': (command, objectName, _) =>
|
'duplicate key value violates unique constraint': (command, objectName, _) =>
|
||||||
new BadRequestException(
|
new WorkspaceQueryRunnerException(
|
||||||
`Cannot ${
|
`Cannot ${
|
||||||
pgGraphQLCommandMapping[command] ?? command
|
pgGraphQLCommandMapping[command] ?? command
|
||||||
} ${objectName} because it violates a uniqueness constraint.`,
|
} ${objectName} because it violates a uniqueness constraint.`,
|
||||||
|
WorkspaceQueryRunnerExceptionCode.QUERY_VIOLATES_UNIQUE_CONSTRAINT,
|
||||||
|
),
|
||||||
|
'violates foreign key constraint': (command, objectName, _) =>
|
||||||
|
new WorkspaceQueryRunnerException(
|
||||||
|
`Cannot ${
|
||||||
|
pgGraphQLCommandMapping[command] ?? command
|
||||||
|
} ${objectName} because it violates a foreign key constraint.`,
|
||||||
|
WorkspaceQueryRunnerExceptionCode.QUERY_VIOLATES_FOREIGN_KEY_CONSTRAINT,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -49,7 +58,7 @@ export const computePgGraphQLError = (
|
|||||||
const errorMessage = error?.message;
|
const errorMessage = error?.message;
|
||||||
|
|
||||||
const mappedErrorKey = Object.keys(pgGraphQLErrorMapping).find(
|
const mappedErrorKey = Object.keys(pgGraphQLErrorMapping).find(
|
||||||
(key) => errorMessage?.startsWith(key),
|
(key) => errorMessage?.includes(key),
|
||||||
);
|
);
|
||||||
|
|
||||||
const mappedError = mappedErrorKey
|
const mappedError = mappedErrorKey
|
||||||
@ -60,7 +69,8 @@ export const computePgGraphQLError = (
|
|||||||
return mappedError(command, objectName, pgGraphqlConfig);
|
return mappedError(command, objectName, pgGraphqlConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new InternalServerErrorException(
|
return new WorkspaceQueryRunnerException(
|
||||||
`GraphQL errors on ${command}${objectName}: ${JSON.stringify(error)}`,
|
`GraphQL errors on ${command}${objectName}: ${JSON.stringify(error)}`,
|
||||||
|
WorkspaceQueryRunnerExceptionCode.INTERNAL_SERVER_ERROR,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
import {
|
||||||
|
WorkspaceQueryRunnerException,
|
||||||
|
WorkspaceQueryRunnerExceptionCode,
|
||||||
|
} from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.exception';
|
||||||
|
import {
|
||||||
|
ForbiddenError,
|
||||||
|
InternalServerError,
|
||||||
|
NotFoundError,
|
||||||
|
TimeoutError,
|
||||||
|
UserInputError,
|
||||||
|
} from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
|
|
||||||
|
export const workspaceQueryRunnerGraphqlApiExceptionHandler = (
|
||||||
|
error: Error,
|
||||||
|
) => {
|
||||||
|
if (error instanceof WorkspaceQueryRunnerException) {
|
||||||
|
switch (error.code) {
|
||||||
|
case WorkspaceQueryRunnerExceptionCode.DATA_NOT_FOUND:
|
||||||
|
throw new NotFoundError(error.message);
|
||||||
|
case WorkspaceQueryRunnerExceptionCode.INVALID_QUERY_INPUT:
|
||||||
|
throw new UserInputError(error.message);
|
||||||
|
case WorkspaceQueryRunnerExceptionCode.QUERY_VIOLATES_UNIQUE_CONSTRAINT:
|
||||||
|
case WorkspaceQueryRunnerExceptionCode.QUERY_VIOLATES_FOREIGN_KEY_CONSTRAINT:
|
||||||
|
case WorkspaceQueryRunnerExceptionCode.TOO_MANY_ROWS_AFFECTED:
|
||||||
|
case WorkspaceQueryRunnerExceptionCode.NO_ROWS_AFFECTED:
|
||||||
|
throw new ForbiddenError(error.message);
|
||||||
|
case WorkspaceQueryRunnerExceptionCode.QUERY_TIMEOUT:
|
||||||
|
throw new TimeoutError(error.message);
|
||||||
|
case WorkspaceQueryRunnerExceptionCode.INTERNAL_SERVER_ERROR:
|
||||||
|
default:
|
||||||
|
throw new InternalServerError(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
};
|
@ -0,0 +1,19 @@
|
|||||||
|
import { CustomException } from 'src/utils/custom-exception';
|
||||||
|
|
||||||
|
export class WorkspaceQueryRunnerException extends CustomException {
|
||||||
|
code: WorkspaceQueryRunnerExceptionCode;
|
||||||
|
constructor(message: string, code: WorkspaceQueryRunnerExceptionCode) {
|
||||||
|
super(message, code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum WorkspaceQueryRunnerExceptionCode {
|
||||||
|
INVALID_QUERY_INPUT = 'INVALID_FIELD_INPUT',
|
||||||
|
DATA_NOT_FOUND = 'DATA_NOT_FOUND',
|
||||||
|
QUERY_TIMEOUT = 'QUERY_TIMEOUT',
|
||||||
|
QUERY_VIOLATES_UNIQUE_CONSTRAINT = 'QUERY_VIOLATES_UNIQUE_CONSTRAINT',
|
||||||
|
QUERY_VIOLATES_FOREIGN_KEY_CONSTRAINT = 'QUERY_VIOLATES_FOREIGN_KEY_CONSTRAINT',
|
||||||
|
TOO_MANY_ROWS_AFFECTED = 'TOO_MANY_ROWS_AFFECTED',
|
||||||
|
NO_ROWS_AFFECTED = 'NO_ROWS_AFFECTED',
|
||||||
|
INTERNAL_SERVER_ERROR = 'INTERNAL_SERVER_ERROR',
|
||||||
|
}
|
@ -1,9 +1,4 @@
|
|||||||
import {
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
BadRequestException,
|
|
||||||
Injectable,
|
|
||||||
Logger,
|
|
||||||
RequestTimeoutException,
|
|
||||||
} from '@nestjs/common';
|
|
||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
|
|
||||||
import isEmpty from 'lodash.isempty';
|
import isEmpty from 'lodash.isempty';
|
||||||
@ -40,8 +35,11 @@ import {
|
|||||||
import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util';
|
import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util';
|
||||||
import { parseResult } from 'src/engine/api/graphql/workspace-query-runner/utils/parse-result.util';
|
import { parseResult } from 'src/engine/api/graphql/workspace-query-runner/utils/parse-result.util';
|
||||||
import { WorkspaceQueryHookService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.service';
|
import { WorkspaceQueryHookService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.service';
|
||||||
|
import {
|
||||||
|
WorkspaceQueryRunnerException,
|
||||||
|
WorkspaceQueryRunnerExceptionCode,
|
||||||
|
} from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.exception';
|
||||||
import { DuplicateService } from 'src/engine/core-modules/duplicate/duplicate.service';
|
import { DuplicateService } from 'src/engine/core-modules/duplicate/duplicate.service';
|
||||||
import { NotFoundError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
|
||||||
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||||
import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event';
|
import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event';
|
||||||
import { ObjectRecordDeleteEvent } from 'src/engine/integrations/event-emitter/types/object-record-delete.event';
|
import { ObjectRecordDeleteEvent } from 'src/engine/integrations/event-emitter/types/object-record-delete.event';
|
||||||
@ -138,7 +136,10 @@ export class WorkspaceQueryRunnerService {
|
|||||||
options: WorkspaceQueryRunnerOptions,
|
options: WorkspaceQueryRunnerOptions,
|
||||||
): Promise<Record | undefined> {
|
): Promise<Record | undefined> {
|
||||||
if (!args.filter || Object.keys(args.filter).length === 0) {
|
if (!args.filter || Object.keys(args.filter).length === 0) {
|
||||||
throw new BadRequestException('Missing filter argument');
|
throw new WorkspaceQueryRunnerException(
|
||||||
|
'Missing filter argument',
|
||||||
|
WorkspaceQueryRunnerExceptionCode.INVALID_QUERY_INPUT,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
const { workspaceId, userId, objectMetadataItem } = options;
|
const { workspaceId, userId, objectMetadataItem } = options;
|
||||||
|
|
||||||
@ -176,14 +177,16 @@ export class WorkspaceQueryRunnerService {
|
|||||||
options: WorkspaceQueryRunnerOptions,
|
options: WorkspaceQueryRunnerOptions,
|
||||||
): Promise<IConnection<TRecord> | undefined> {
|
): Promise<IConnection<TRecord> | undefined> {
|
||||||
if (!args.data && !args.ids) {
|
if (!args.data && !args.ids) {
|
||||||
throw new BadRequestException(
|
throw new WorkspaceQueryRunnerException(
|
||||||
'You have to provide either "data" or "id" argument',
|
'You have to provide either "data" or "id" argument',
|
||||||
|
WorkspaceQueryRunnerExceptionCode.INVALID_QUERY_INPUT,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args.ids && isEmpty(args.data)) {
|
if (!args.ids && isEmpty(args.data)) {
|
||||||
throw new BadRequestException(
|
throw new WorkspaceQueryRunnerException(
|
||||||
'The "data" condition can not be empty when ID input not provided',
|
'The "data" condition can not be empty when ID input not provided',
|
||||||
|
WorkspaceQueryRunnerExceptionCode.INVALID_QUERY_INPUT,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +208,10 @@ export class WorkspaceQueryRunnerService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!existingRecords || existingRecords.length === 0) {
|
if (!existingRecords || existingRecords.length === 0) {
|
||||||
throw new NotFoundError(`Object with id ${args.ids} not found`);
|
throw new WorkspaceQueryRunnerException(
|
||||||
|
`Object with id ${args.ids} not found`,
|
||||||
|
WorkspaceQueryRunnerExceptionCode.DATA_NOT_FOUND,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,7 +392,10 @@ export class WorkspaceQueryRunnerService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!existingRecord) {
|
if (!existingRecord) {
|
||||||
throw new NotFoundError(`Object with id ${args.id} not found`);
|
throw new WorkspaceQueryRunnerException(
|
||||||
|
`Object with id ${args.id} not found`,
|
||||||
|
WorkspaceQueryRunnerExceptionCode.DATA_NOT_FOUND,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const query = await this.workspaceQueryBuilderFactory.updateOne(
|
const query = await this.workspaceQueryBuilderFactory.updateOne(
|
||||||
@ -681,8 +690,9 @@ export class WorkspaceQueryRunnerService {
|
|||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (isQueryTimeoutError(error)) {
|
if (isQueryTimeoutError(error)) {
|
||||||
throw new RequestTimeoutException(
|
throw new WorkspaceQueryRunnerException(
|
||||||
'The SQL request took too long to process, resulting in a query read timeout. To resolve this issue, consider modifying your query by reducing the depth of relationships or limiting the number of records being fetched.',
|
'The SQL request took too long to process, resulting in a query read timeout. To resolve this issue, consider modifying your query by reducing the depth of relationships or limiting the number of records being fetched.',
|
||||||
|
WorkspaceQueryRunnerExceptionCode.QUERY_TIMEOUT,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -733,7 +743,10 @@ export class WorkspaceQueryRunnerService {
|
|||||||
['update', 'deleteFrom'].includes(command) &&
|
['update', 'deleteFrom'].includes(command) &&
|
||||||
!result.affectedCount
|
!result.affectedCount
|
||||||
) {
|
) {
|
||||||
throw new BadRequestException('No rows were affected.');
|
throw new WorkspaceQueryRunnerException(
|
||||||
|
'No rows were affected.',
|
||||||
|
WorkspaceQueryRunnerExceptionCode.NO_ROWS_AFFECTED,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errors && errors.length > 0) {
|
if (errors && errors.length > 0) {
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
||||||
import {
|
import {
|
||||||
CreateManyResolverArgs,
|
CreateManyResolverArgs,
|
||||||
Resolver,
|
Resolver,
|
||||||
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
||||||
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
|
||||||
|
|
||||||
|
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
|
||||||
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -24,15 +25,19 @@ export class CreateManyResolverFactory
|
|||||||
): Resolver<CreateManyResolverArgs> {
|
): Resolver<CreateManyResolverArgs> {
|
||||||
const internalContext = context;
|
const internalContext = context;
|
||||||
|
|
||||||
return (_source, args, context, info) => {
|
return async (_source, args, context, info) => {
|
||||||
return this.workspaceQueryRunnerService.createMany(args, {
|
try {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
return await this.workspaceQueryRunnerService.createMany(args, {
|
||||||
workspaceId: internalContext.workspaceId,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
userId: internalContext.userId,
|
workspaceId: internalContext.workspaceId,
|
||||||
info,
|
userId: internalContext.userId,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
info,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
});
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
||||||
import {
|
import {
|
||||||
CreateOneResolverArgs,
|
CreateOneResolverArgs,
|
||||||
Resolver,
|
Resolver,
|
||||||
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
||||||
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
|
||||||
|
|
||||||
|
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
|
||||||
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -24,15 +25,19 @@ export class CreateOneResolverFactory
|
|||||||
): Resolver<CreateOneResolverArgs> {
|
): Resolver<CreateOneResolverArgs> {
|
||||||
const internalContext = context;
|
const internalContext = context;
|
||||||
|
|
||||||
return (_source, args, context, info) => {
|
return async (_source, args, context, info) => {
|
||||||
return this.workspaceQueryRunnerService.createOne(args, {
|
try {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
return await this.workspaceQueryRunnerService.createOne(args, {
|
||||||
workspaceId: internalContext.workspaceId,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
userId: internalContext.userId,
|
workspaceId: internalContext.workspaceId,
|
||||||
info,
|
userId: internalContext.userId,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
info,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
});
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
||||||
import {
|
import {
|
||||||
DeleteManyResolverArgs,
|
DeleteManyResolverArgs,
|
||||||
Resolver,
|
Resolver,
|
||||||
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
||||||
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
|
||||||
|
|
||||||
|
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
|
||||||
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -24,15 +25,19 @@ export class DeleteManyResolverFactory
|
|||||||
): Resolver<DeleteManyResolverArgs> {
|
): Resolver<DeleteManyResolverArgs> {
|
||||||
const internalContext = context;
|
const internalContext = context;
|
||||||
|
|
||||||
return (_source, args, context, info) => {
|
return async (_source, args, context, info) => {
|
||||||
return this.workspaceQueryRunnerService.deleteMany(args, {
|
try {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
return await this.workspaceQueryRunnerService.deleteMany(args, {
|
||||||
workspaceId: internalContext.workspaceId,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
userId: internalContext.userId,
|
workspaceId: internalContext.workspaceId,
|
||||||
info,
|
userId: internalContext.userId,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
info,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
});
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
||||||
import {
|
import {
|
||||||
DeleteOneResolverArgs,
|
DeleteOneResolverArgs,
|
||||||
Resolver,
|
Resolver,
|
||||||
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
||||||
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
|
||||||
|
|
||||||
|
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
|
||||||
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -24,15 +25,19 @@ export class DeleteOneResolverFactory
|
|||||||
): Resolver<DeleteOneResolverArgs> {
|
): Resolver<DeleteOneResolverArgs> {
|
||||||
const internalContext = context;
|
const internalContext = context;
|
||||||
|
|
||||||
return (_source, args, context, info) => {
|
return async (_source, args, context, info) => {
|
||||||
return this.workspaceQueryRunnerService.deleteOne(args, {
|
try {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
return await this.workspaceQueryRunnerService.deleteOne(args, {
|
||||||
workspaceId: internalContext.workspaceId,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
userId: internalContext.userId,
|
workspaceId: internalContext.workspaceId,
|
||||||
info,
|
userId: internalContext.userId,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
info,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
});
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import {
|
|
||||||
Resolver,
|
|
||||||
FindOneResolverArgs,
|
|
||||||
ExecuteQuickActionOnOneResolverArgs,
|
|
||||||
DeleteOneResolverArgs,
|
|
||||||
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
|
||||||
import { Record as IRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface';
|
import { Record as IRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface';
|
||||||
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
|
||||||
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
|
||||||
import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||||
|
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
||||||
|
import {
|
||||||
|
DeleteOneResolverArgs,
|
||||||
|
ExecuteQuickActionOnOneResolverArgs,
|
||||||
|
FindOneResolverArgs,
|
||||||
|
Resolver,
|
||||||
|
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
|
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
||||||
|
|
||||||
|
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
|
||||||
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
||||||
import { QuickActionsService } from 'src/engine/core-modules/quick-actions/quick-actions.service';
|
import { QuickActionsService } from 'src/engine/core-modules/quick-actions/quick-actions.service';
|
||||||
|
|
||||||
@ -30,15 +31,19 @@ export class ExecuteQuickActionOnOneResolverFactory
|
|||||||
): Resolver<ExecuteQuickActionOnOneResolverArgs> {
|
): Resolver<ExecuteQuickActionOnOneResolverArgs> {
|
||||||
const internalContext = context;
|
const internalContext = context;
|
||||||
|
|
||||||
return (_source, args, context, info) => {
|
return async (_source, args, context, info) => {
|
||||||
return this.executeQuickActionOnOne(args, {
|
try {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
return await this.executeQuickActionOnOne(args, {
|
||||||
userId: internalContext.userId,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
workspaceId: internalContext.workspaceId,
|
userId: internalContext.userId,
|
||||||
info,
|
workspaceId: internalContext.workspaceId,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
info,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
});
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
||||||
import {
|
import {
|
||||||
FindDuplicatesResolverArgs,
|
FindDuplicatesResolverArgs,
|
||||||
Resolver,
|
Resolver,
|
||||||
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
||||||
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
|
||||||
|
|
||||||
|
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
|
||||||
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -24,15 +25,19 @@ export class FindDuplicatesResolverFactory
|
|||||||
): Resolver<FindDuplicatesResolverArgs> {
|
): Resolver<FindDuplicatesResolverArgs> {
|
||||||
const internalContext = context;
|
const internalContext = context;
|
||||||
|
|
||||||
return (_source, args, context, info) => {
|
return async (_source, args, context, info) => {
|
||||||
return this.workspaceQueryRunnerService.findDuplicates(args, {
|
try {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
return await this.workspaceQueryRunnerService.findDuplicates(args, {
|
||||||
workspaceId: internalContext.workspaceId,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
userId: internalContext.userId,
|
workspaceId: internalContext.workspaceId,
|
||||||
info,
|
userId: internalContext.userId,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
info,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
});
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
||||||
import {
|
import {
|
||||||
FindManyResolverArgs,
|
FindManyResolverArgs,
|
||||||
Resolver,
|
Resolver,
|
||||||
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
||||||
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
|
||||||
|
|
||||||
|
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
|
||||||
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -24,15 +25,19 @@ export class FindManyResolverFactory
|
|||||||
): Resolver<FindManyResolverArgs> {
|
): Resolver<FindManyResolverArgs> {
|
||||||
const internalContext = context;
|
const internalContext = context;
|
||||||
|
|
||||||
return (_source, args, context, info) => {
|
return async (_source, args, context, info) => {
|
||||||
return this.workspaceQueryRunnerService.findMany(args, {
|
try {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
return await this.workspaceQueryRunnerService.findMany(args, {
|
||||||
workspaceId: internalContext.workspaceId,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
userId: internalContext.userId,
|
workspaceId: internalContext.workspaceId,
|
||||||
info,
|
userId: internalContext.userId,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
info,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
});
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
||||||
import {
|
import {
|
||||||
FindOneResolverArgs,
|
FindOneResolverArgs,
|
||||||
Resolver,
|
Resolver,
|
||||||
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
||||||
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
|
||||||
|
|
||||||
|
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
|
||||||
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -24,15 +25,19 @@ export class FindOneResolverFactory
|
|||||||
): Resolver<FindOneResolverArgs> {
|
): Resolver<FindOneResolverArgs> {
|
||||||
const internalContext = context;
|
const internalContext = context;
|
||||||
|
|
||||||
return (_source, args, context, info) => {
|
return async (_source, args, context, info) => {
|
||||||
return this.workspaceQueryRunnerService.findOne(args, {
|
try {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
return await this.workspaceQueryRunnerService.findOne(args, {
|
||||||
workspaceId: internalContext.workspaceId,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
userId: internalContext.userId,
|
workspaceId: internalContext.workspaceId,
|
||||||
info,
|
userId: internalContext.userId,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
info,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
});
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
||||||
import {
|
import {
|
||||||
Resolver,
|
Resolver,
|
||||||
UpdateManyResolverArgs,
|
UpdateManyResolverArgs,
|
||||||
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
||||||
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
|
||||||
|
|
||||||
|
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
|
||||||
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -24,15 +25,19 @@ export class UpdateManyResolverFactory
|
|||||||
): Resolver<UpdateManyResolverArgs> {
|
): Resolver<UpdateManyResolverArgs> {
|
||||||
const internalContext = context;
|
const internalContext = context;
|
||||||
|
|
||||||
return (_source, args, context, info) => {
|
return async (_source, args, context, info) => {
|
||||||
return this.workspaceQueryRunnerService.updateMany(args, {
|
try {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
return await this.workspaceQueryRunnerService.updateMany(args, {
|
||||||
workspaceId: internalContext.workspaceId,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
userId: internalContext.userId,
|
workspaceId: internalContext.workspaceId,
|
||||||
info,
|
userId: internalContext.userId,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
info,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
});
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
||||||
import {
|
import {
|
||||||
Resolver,
|
Resolver,
|
||||||
UpdateOneResolverArgs,
|
UpdateOneResolverArgs,
|
||||||
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
||||||
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
|
||||||
|
|
||||||
|
import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util';
|
||||||
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -24,15 +25,19 @@ export class UpdateOneResolverFactory
|
|||||||
): Resolver<UpdateOneResolverArgs> {
|
): Resolver<UpdateOneResolverArgs> {
|
||||||
const internalContext = context;
|
const internalContext = context;
|
||||||
|
|
||||||
return (_source, args, context, info) => {
|
return async (_source, args, context, info) => {
|
||||||
return this.workspaceQueryRunnerService.updateOne(args, {
|
try {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
return await this.workspaceQueryRunnerService.updateOne(args, {
|
||||||
workspaceId: internalContext.workspaceId,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
userId: internalContext.userId,
|
workspaceId: internalContext.workspaceId,
|
||||||
info,
|
userId: internalContext.userId,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
info,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
});
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
workspaceQueryRunnerGraphqlApiExceptionHandler(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,150 +0,0 @@
|
|||||||
import {
|
|
||||||
OnExecuteDoneHookResultOnNextHook,
|
|
||||||
Plugin,
|
|
||||||
getDocumentString,
|
|
||||||
handleStreamOrSingleExecutionResult,
|
|
||||||
} from '@envelop/core';
|
|
||||||
import { GraphQLError, Kind, OperationDefinitionNode, print } from 'graphql';
|
|
||||||
|
|
||||||
import { GraphQLContext } from 'src/engine/api/graphql/graphql-config/interfaces/graphql-context.interface';
|
|
||||||
|
|
||||||
import { ExceptionHandlerService } from 'src/engine/integrations/exception-handler/exception-handler.service';
|
|
||||||
import {
|
|
||||||
convertExceptionToGraphQLError,
|
|
||||||
shouldFilterException,
|
|
||||||
} from 'src/engine/utils/global-exception-handler.util';
|
|
||||||
|
|
||||||
export type ExceptionHandlerPluginOptions = {
|
|
||||||
/**
|
|
||||||
* The exception handler service to use.
|
|
||||||
*/
|
|
||||||
exceptionHandlerService: ExceptionHandlerService;
|
|
||||||
/**
|
|
||||||
* The key of the event id in the error's extension. `null` to disable.
|
|
||||||
* @default exceptionEventId
|
|
||||||
*/
|
|
||||||
eventIdKey?: string | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// This hook is deprecated.
|
|
||||||
// We should either handle exception in the context of graphql, controller or command
|
|
||||||
// @deprecated
|
|
||||||
export const useExceptionHandler = <PluginContext extends GraphQLContext>(
|
|
||||||
options: ExceptionHandlerPluginOptions,
|
|
||||||
): Plugin<PluginContext> => {
|
|
||||||
const eventIdKey = options.eventIdKey === null ? null : 'exceptionEventId';
|
|
||||||
|
|
||||||
function addEventId(
|
|
||||||
err: GraphQLError,
|
|
||||||
eventId: string | undefined | null,
|
|
||||||
): GraphQLError {
|
|
||||||
if (eventIdKey !== null && eventId) {
|
|
||||||
err.extensions[eventIdKey] = eventId;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
async onExecute({ args }) {
|
|
||||||
const exceptionHandlerService = options.exceptionHandlerService;
|
|
||||||
const rootOperation = args.document.definitions.find(
|
|
||||||
(o) => o.kind === Kind.OPERATION_DEFINITION,
|
|
||||||
) as OperationDefinitionNode;
|
|
||||||
const operationType = rootOperation.operation;
|
|
||||||
const user = args.contextValue.req.user;
|
|
||||||
const document = getDocumentString(args.document, print);
|
|
||||||
const opName =
|
|
||||||
args.operationName ||
|
|
||||||
rootOperation.name?.value ||
|
|
||||||
'Anonymous Operation';
|
|
||||||
|
|
||||||
return {
|
|
||||||
onExecuteDone(payload) {
|
|
||||||
const handleResult: OnExecuteDoneHookResultOnNextHook<object> = ({
|
|
||||||
result,
|
|
||||||
setResult,
|
|
||||||
}) => {
|
|
||||||
if (result.errors && result.errors.length > 0) {
|
|
||||||
const exceptions = result.errors.reduce<{
|
|
||||||
filtered: any[];
|
|
||||||
unfiltered: any[];
|
|
||||||
}>(
|
|
||||||
(acc, err) => {
|
|
||||||
// Filter out exceptions that we don't want to be captured by exception handler
|
|
||||||
if (shouldFilterException(err?.originalError ?? err)) {
|
|
||||||
acc.filtered.push(err);
|
|
||||||
} else {
|
|
||||||
acc.unfiltered.push(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filtered: [],
|
|
||||||
unfiltered: [],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (exceptions.unfiltered.length > 0) {
|
|
||||||
const eventIds = exceptionHandlerService.captureExceptions(
|
|
||||||
exceptions.unfiltered,
|
|
||||||
{
|
|
||||||
operation: {
|
|
||||||
name: opName,
|
|
||||||
type: operationType,
|
|
||||||
},
|
|
||||||
document,
|
|
||||||
user,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
exceptions.unfiltered.map((err, i) =>
|
|
||||||
addEventId(err, eventIds?.[i]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const concatenatedErrors = [
|
|
||||||
...exceptions.filtered,
|
|
||||||
...exceptions.unfiltered,
|
|
||||||
];
|
|
||||||
const errors = concatenatedErrors.map((err) => {
|
|
||||||
if (!err.originalError) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return convertExceptionToGraphQLError(err.originalError);
|
|
||||||
});
|
|
||||||
|
|
||||||
setResult({
|
|
||||||
...result,
|
|
||||||
errors,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return handleStreamOrSingleExecutionResult(payload, handleResult);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
onValidate: ({ context, validateFn, params: { documentAST, schema } }) => {
|
|
||||||
const errors = validateFn(schema, documentAST);
|
|
||||||
|
|
||||||
if (Array.isArray(errors) && errors.length > 0) {
|
|
||||||
const headers = context.req.headers;
|
|
||||||
const currentSchemaVersion = context.req.cacheVersion;
|
|
||||||
|
|
||||||
const requestSchemaVersion = headers['x-schema-version'];
|
|
||||||
|
|
||||||
if (
|
|
||||||
requestSchemaVersion &&
|
|
||||||
requestSchemaVersion !== currentSchemaVersion
|
|
||||||
) {
|
|
||||||
throw new GraphQLError(
|
|
||||||
`Schema version mismatch, please refresh the page.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
Loading…
Reference in New Issue
Block a user